GWT MVP with Places & Activities - Where's the Model? - gwt

I'm trying to familiarize myself with the "Places & Activities" design pattern for GWT development, and so far I think it has a lot of potential. I especially like the way how once you start thinking about your application in terms of "Places", browser history virtually just lands in your lap with almost no extra effort.
However, one thing just bothers me: All the articles and code examples I've seen so far gloss over one (as far as I am concerned, major) aspect: the 'M' part of the 'MVP', i.e. the Model!
In normal MVP architecture, as far as I understand it, the Presenter holds a reference to the Model, and is responsible for updating it according to UI events or, respectivly, updating the UI according to Model changes.
Now, in all the articles/samples for "P&A" the Activities seem to be taking the place of the Presenter, but unlike 'normal' Presenters, they get discarded and (re-)created whenever a new Place arrives, so they can't be the ones to store the client state, or it would be lost every time. Activities are cheap to create, so it's not much of a hassle, but I wouldn't want to create the model of a complex application over and over again.
All the samples are fairly simple and don't have much of a state and therefore just ignore the Model aspect, but where would an actual, complex application store its state?

I think I found my own answer. The main problem seems to be that all of the simple code examples make the Activities be the Presenters, as in:
public class NavigationActivity extends AbstractActivity implements NavigationView.Presenter {
private final ClientFactory clientFactory;
private final NavigationPlace place;
public NavigationActivity(ClientFactory clientFactory, NavigationPlace place) {
this.clientFactory = clientFactory;
this.place = place;
}
#Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
NavigationView navView = clientFactory.getNavigationView();
navView.setSearchTerm(place.getSearchTerm());
navView.setPresenter(this);
panel.setWidget(navView);
}
#Override
public void goTo(Place place) {
clientFactory.getPlaceController().goTo(place);
}
}
Now Activities are fairly short-lived, whereas a typical Presenter in the 'classical' sense has a much longer lifespan in order to maintain the binding between the model and the UI. So what I did was to implement a separate Presenter using the standard MVP design pattern, and all the Activity does is something like this:
public class NavigationActivity extends AbstractActivity {
private final ClientFactory clientFactory;
private final NavigationPlace place;
public NavigationActivity(ClientFactory clientFactory, NavigationPlace place) {
this.clientFactory = clientFactory;
this.place = place;
}
#Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
NavigationPresenter presenter = clientFactory.getNavigationPresenter();
presenter.setSearchTerm(place.getSearchTerm());
presenter.go(panel);
}
}
So, instead of the Activity fetching the View, and acting like a Presenter on it, it fetches the actual Presenter, just informs it of the client state change induced by the Place, and tells it where to display its information (i.e. the view). And the Presenter is then free to manage the view and the model any way it likes - this way works a lot better (at least with what I have in mind for the application I'm working on) than the code examples I have found so far.

You're right, almost always the presenter is the only guy holding the model and managing its lifetime. Model from previous GWT versions has simply been a DTO, (and continues to be) a POJO which are created by the GWT deserializer when RPC methods return, or created by Presenters and filled with UI data by UIHandlers, and sent to the server.
I have taken efforts, to keep the Models lifetime encapsulated within the Activities lifetime, and avoided storing state outside of activities. (I do however have a singleton Global State maintained for use from anywhere in the application.) This I think is what GWT MVP engineers assumed will happen - It makes sense when, say the user has navigated away from a Place, for the models associated with that place also to get disposed (& collected). Create models, fill them up inside the activities, and make service calls to update the server before navigating away (or triggered by some control on the page), and let them go along with the activity - is what I have been doing till date.
A bigger project I have been involved in faced quite a few browser memory footprint issues, and all of them were due to objects which are associated with another (not currently viewed) Place being in memory. It was hard to track and remove references to these objects, and since the user has navigated away from the screen - the "why are my old screen objects still in memory?" question cropped up frequently and subsequently got fixed. This is why, upfront, I chose to keep the Model's lifetime encapsulated within the Activities lifetime in my current pet project.
If you have models that span across (that are filled/accessed by) several activities (as is the case if you have sidebars & master/container widgets), some redesigning of models maybe in order, if you have examples I will try and help.

Related

Is it possible to implement a module that is not a WPF module (a standard class library, no screens)?

I am developing a modular WPF application with Prism in .Net Core 5.0 (using MVVM, DryIoc) and I would like to have a module that is not a WPF module, i.e., a module with functionality that can be used by any other module. I don't want any project reference, because I want to keep the loosely coupled idea of the modules.
My first question is: is it conceptually correct? Or is it mandatory that a module has a screen? I guess it should be ok.
The second and more important (for me) is, what would be the best way to create the instance?
This is the project (I know I should review the names in this project):
HotfixSearcher is the main class, the one I need to get instantiated. In this class, for example, I subscribe to some events.
And this is the class that implements the IModule interface (the module class):
namespace SearchHotfix.Library
{
public class HotfixSearcherModule : IModule
{
public HotfixSearcherModule()
{
}
public void OnInitialized(IContainerProvider containerProvider)
{
//Create Searcher instance
var searcher = containerProvider.Resolve<IHotfixSearcher>();
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IHotfixSearcher, HotfixSearcher>();
}
}
}
That is the only way I found to get the class instantiated, but I am not a hundred per cent comfortable with creating an instance that is not used, I think it does not make much sense.
For modules that have screens, the instances get created when navigating to them using the RequestNavigate method:
_regionManager.RequestNavigate(RegionNames.ContentRegion, "ContentView");
But since this is only a library with no screens, I can't find any other way to get this instantiated.
According to Prism documentation, subscribing to an event shoud be enough but I tried doing that from within my main class HotfixSearcher but it does not work (breakpoints on constructor or on the event handler of the event to which I subscribe are never hit).
When I do this way, instead, the instance is created, I hit the constructor breakpoint, and obviously the instance is subscribed to the event since it is done in the constructor.
To sum up, is there a way to get rid of that var searcher = containerProvider.Resolve<IHotfixSearcher>(); and a better way to achieve this?
Thanks in advance!
Or is it mandatory that a module has a screen?
No, of course not, modules have nothing to do with views or view models. They are just a set of registrations with the container.
what would be the best way to create the instance?
Let the container do the work. Normally, you have (at least) one assembly that only contains public interfaces (and the associated enums), but no modules. You reference that from the module and register the module's implementations of the relevant interfaces withing the module's Initialize method. Some other module (or the main app) can then have classes that get the interfaces as constructor parameters, and the container will resolve (i.e. create) the concrete types registered in the module, although they are internal or even private and completely unknown outside the module.
This is as loose a coupling as it gets if you don't want to sacrifice strong typing.
is there a way to get rid of that var searcher = containerProvider.Resolve<IHotfixSearcher>(); and a better way to achieve this?
You can skip the var searcher = part :-) But if the HotfixSearcher is never injected anywhere, it won't be created unless you do it yourself. OnInitialized is the perfect spot for this, because it runs after all modules had their chance to RegisterTypes so all dependencies should be registered.
If HotfixSearcher is not meant to be injected, you can also drop IHotfixSearcher and resolve HotfixSearcher directly:
public void OnInitialized(IContainerProvider containerProvider)
{
containerProvider.Resolve<HotfixSearcher>();
}
I am not a hundred per cent comfortable with creating an instance that is not used, I think it does not make much sense.
It is used, I suppose, although not through calling one of its methods. It's used by sending it an event. That's just fine. Think of it like Task.Run - it's fine for the task to exist in seeming isolation, too.

Implementing Bounded Context with Entity Framework in a 3-Layer Architecture

I have watched Julie Lerman's videos about using EF in an enterprise application. Now I am developing a website using "Bounded Contexts" and other stuff she has taught in that series.
The problem is I do not know how to use bounded contexts (BC) from within my "Business Layer". To make it clearer: How should the BL know that which specific BC it should use.
Suppose the UI requests a list of products from the business layer. In BL I have a method that returns a list of products: GetAll(). This method does not know which part of the UI (site admin, moderator or public user) has requested the list of products. Since each user/scenario has its own bounded context, the list needs to be pulled using that related context. How should the BL choose the appropriate BC?
Moreover I do not want the UI layer to interact with data layer.
How can this be done?
If by business layer you mean a place where all your business rules are defined, then that is a bounded context.
A bounded context looks at your system from a certain angle so that business rules can be implemented in a compartmentalised fashion (with the goal that it is easier to handle the overall problem by splitting in to smaller chunks).
http://martinfowler.com/bliki/BoundedContext.html
Front-end
So assuming you have a ASP MVC front end, this controllers are the things that will call your use cases/user stories that are presented from the domain to be called via a standard known interface.
public class UserController : Controller
{
ICommandHandler<ChangeNameCommand> handler;
public UserController(ICommandHandler<ChangeNameCommand> handler)
{
this.handler = handler;
}
public ActionResult ChangeUserName(string id, string name)
{
try
{
var command = new ChangeNameCommand(id,name);
var data = handler.handle(command);
}
catch(Exception e)
{
// add error logging and display info
ViewBag.Error = e.Message;
}
// everything went OK, let the user know
return View("Index");
}
}
Domain Application (Use Cases)
Next, you would have an domain application entry point that implements the use case (this would be a command or query handler).
You may call this directly and have the code run in-process with your front end application, or you may have a WebAPI or WCF service in front of it presenting the domain application services. It doesn't really matter, how you the system is distrusted depends on the system requirements (it is often simpler from an infrastructure perspective to not to distribute if not needed).
The domain application layer then orchestrates the user story - it will new up repositories, fetch entities, perform an operation on them, and then write back to the repository. The code here should not be complex or contain logic.
public class NewUserHandler : ICommandHandler<ChangeNameCommand>
{
private readonly IRepository repository;
public NewUserHandler(IRepository repository)
{
this.repository = repository;
}
public void Handle(ChangeUserName command)
{
var userId = new UserId(command.UserId);
var user = this.repository.GetById<User>(userId);
user.ChangeName(command.NewName);
this.repository.Save(newUser);
}
}
Domain Model
The entities them selves implement their own business logic in the domain model. You may also have domain services for logic which doesn't naturally fit nicely inside an individual entity.
public class User
{
protected string Name;
protected DateTime NameLastChangedOn;
public ChangeName(string newName)
{
// not the best of business rules, just an example...
if((DateTime.UtcNow - NameLastChangedOn).Days < 30)
{
throw new DomainException("Cannot change name more than once every 30 days");
}
this.Name = newName;
this.NameLastChangedOn = DateTime.UtcNow;
}
}
Infrastructure
You would have infrastructure which implements the code to fetch and retrieve entities from your backing store. For you this is Entity Framework and the DbContext (my example code above is not using EF but you can substitute).
Answer to your question - Which bounded context should the front end application call?
Not to make the answer complex or long, but I included the above code to set the background and hope to make it easier to understand as I think the terms you are using are getting a little mixed up.
With the above code as you started implementing more command and query handlers, which bounded context is called from your front end application depends on what specific user story the user wishes to perform.
User stories will generally be clustered across different bounded contexts, so you would just select the command or query for the bounded context that implements the required functionality - don't worry about making it anything more complicated than that.
Let the problem you are trying to solve dictate the mapping, and dont be afraid that this mapping will possibly change as insight in to the problem you are looking to solve improves.
Sidenote
As a side note to mention things I found useful (I started my DDD journey with EF)... with entity framework there are ORM concepts that are often required such as defining mapping relationships and navigation properties between entities, and what happens with cascade deletes and updates. For me, this started to influence how I designed my entities, rather than the problem dictating how the entities should be designed. You may find this interesting: http://mehdi.me/ambient-dbcontext-in-ef6/
You may also want to look at http://geteventstore.com and event sourcing which takes away any headaches of ORM mapping (but comes with added complexity and workarounds needed to get acceptable performance). What is best to use depends on the situation, but its always good to know all the options.
I also use SimpleInjector to wire up my classes and inject in to the MVC controller (as a prebuilt Command or Query handler), more info here: https://cuttingedge.it/blogs/steven/pivot/entry.php?id=91.
Using an IoC container is a personal preference only and not set in stone.
This book is also awesome: https://vaughnvernon.co/?page_id=168
I mention the above as I started my DDD journey with EF and the exact same question you had.

Entity Framework Inheritance and Logic

I've been creating a prototype for a modern MUD engine. A MUD is a simple form of simulation and provide a good method in which to test a concept I'm working on. This has led me to a couple of places in my code where things, are a bit unclear, and the design is coming into question (probably due to its being flawed). I'm using model first (I may need to change this) and I've designed a top down architecture of game objects. I may be doing this completely wrong.
What I've done is create a MUDObject entity. This entity is effectively a base for all of my other logical constructs, such as characters, their items, race, etc. I've also created a set of three meta classes which are used for logical purposes as well Attributes, Events, and Flags. They are fairly straightforward, and are all inherited from MUDObject.
The MUDObject class is designed to provide default data behavior for all of the objects, this includes deletion of dead objects. The automatically clearing of floors. etc. This is also designed to facilitate this logic virtually if needed. For example, checking a room to see if an effect has ended and deleting the the effect (remove the flag).
public partial class MUDObject
{
public virtual void Update()
{
if (this.LifeTime.Value.CompareTo(DateTime.Now) > 0)
{
using (var context = new ReduxDataContext())
{
context.MUDObjects.DeleteObject(this);
}
}
}
public virtual void Pause()
{
}
public virtual void Resume()
{
}
public virtual void Stop()
{
}
}
I've also got a class World, it is derived from MUDObject and contains the areas and room (which in turn contain the games objects) and handles the timer for the operation to run the updates. (probably going to be moved, put here as if it works would limit it to only the objects in-world at the time.)
public partial class World
{
private Timer ticker;
public void Start()
{
this.ticker = new Timer(3000.0);
this.ticker.Elapsed += ticker_Elapsed;
this.ticker.Start();
}
private void ticker_Elapsed(object sender, ElapsedEventArgs e)
{
this.Update();
}
public override void Update()
{
this.CurrentTime += 3;
// update contents
base.Update();
}
public override void Pause()
{
this.ticker.Enabled = false;
// update contents
base.Pause();
}
public override void Resume()
{
this.ticker.Enabled = true;
// update contents
this.Resume();
}
public override void Stop()
{
this.ticker.Stop();
// update contents
base.Stop();
}
}
I'm curious of two things.
Is there a way to recode the context so that it has separate
ObjectSets for each type derived from MUDObject?
i.e. context.MUDObjects.Flags or context.Flags
If not how can I query a child type specifically?
Does the Update/Pause/Resume/Stop architecture I'm using work
properly when placed into the EF entities directly? given than it's for
data purposes only?
Will locking be an issue?
Does the partial class automatically commit changes when they are made?
Would I be better off using a flat repository and doing this in the game engine directly?
1) Is there a way to recode the context so that it has separate ObjectSets for each type derived from MUDObject?
Yes, there is. If you decide that you want to define a base class for all your entities it is common to have an abstract base class that is not part of the entity framework model. The model only contains the derived types and the context contains DbSets of derived types (if it is a DbContext) like
public DbSet<Flag> Flags { get; set; }
If appropriate you can implement inheritance between classes, but that would be to express polymorphism, not to implement common persistence-related behaviour.
2) Does the Update/Pause/Resume/Stop architecture I'm using work properly when placed into the EF entities directly?
No. Entities are not supposed to know anything about persistence. The context is responsible for creating them, tracking their changes and updating/deleting them. I think that also answers your question about automatically committing changes: no.
Elaboration:
I think here it's good to bring up the single responsibility principle. A general pattern would be to
let a context populate objects from a store
let the object act according to their responsibilities (the simulation)
let a context store their state whenever necessary
I think Pause/Resume/Stop could be responsibilities of MUD objects. Update is an altogether different kind of action and responsibility.
Now I have to speculate, but take your World class. You should be able to express its responsibility in a short phrase, maybe something like "harbour other objects" or "define boundaries". I don't think it should do the timing. I think the timing should be the responsibility of some core utility which signals that a time interval has elapsed. Other objects know how to respond to that (e.g. do some state change, or, the context or repository, save changes).
Well, this is only an example of how to think about it, probably far from correct.
One other thing is that I think saving changes should be done not nearly as often as state changes of the objects that carry out the simulation. It would probably slow down the process dramatically. Maybe it should be done in longer intervals or by a user action.
First thing to say, if you are using EF 4.1 (as it is tagged) you should really consider going to version 5.0 (you will need to make a .NET 4.5 project for this)
With several improvements on performance, you can benefit from other features also. The code i will show you will work for 5.0 (i dont know if it will work for 4.1 version)
Now, let's go to you several questions:
Is there a way to recode the context so that it has separate
ObjectSets for each type derived from MUDObject? If not how can I
query a child type specifically?
i.e. context.MUDObjects.Flags or context.Flags
Yes, you can. But to call is a little different, you will not have Context.Worlds you will only have the base class to be called this way, if you want to get the set of Worlds (that inherit from MUDObject, you will call:
var worlds = context.MUDObjects.OfType<World>();
Or you can do in direct way by using generics:
var worlds = context.Set<World>();
If you define you inheritance the right way, you should have an abstract class called MUDObjects and all others should iherit from that class. EF can work perfectly with this, you just need to make it right.
Does the Update/Pause/Resume/Stop architecture I'm using work properly
when placed into the EF entities directly? given than it's for data
purposes only?
In this case i think you should consider using a Design Pattern called Strategy Pattern, do some research, it will fit your objects.
Will locking be an issue?
Depends on how you develop the system....
Does the partial class automatically commit changes when they are
made?
Did not understand that question.... Partial classes are just like regular classes, thay are just in different files, but when compiled (or event at Design-Time, because of the vshost.exe) they are in fact just one.
Would I be better off using a flat repository and doing this in the
game engine directly?
Hard to answer, it all depends on the requirements of the game, deploy strategy....

GWT MVP updating Activity state on Place change

What is the best practise to update Activity state on Place change? Imagine you have an activity with view that displays list of categories and list of items in the category. If different category is selected then app goes to new place with category ID. I want then to only refresh items and not to create new activity that also re-reads category list.
My current approach is like this:
public class AppActivityMapper implements ActivityMapper {
private ItemListActivity itemListActivity;
...
public Activity getActivity(final Place place) {
final Activity activity;
if (place instanceof ItemListPlace) {
if (itemListActivity == null) {
itemListActivity = new ItemListActivity((ItemListPlace) place, clientFactory);
} else {
itemListActivity.refresh((ItemListPlace) place);
}
activity = itemListActivity;
} else {
itemListActivity = null;
}
...
return activity;
}
...
Alternatives are:
listen to PlaceChangeEvents from within the activity (you can then use a FilteredActivityMapper and CachingActivityMapper for the caching of the activity in your ActivityMapper, so that it's reduced to only create a new activity when asked). †
have some component listen to PlaceChangeEvents and translate them to business-oriented events, the activity then listens to those events rather than PlaceChangeEvents, otherwise the same as above.
decouple the activity from the "screen", make the "screen" a singleton with a reset() method and call that method from the activity's start (possibly passing the category ID as an argument in this case). The "screen" being a singleton could then make sure to load the categories list only once.
in your case, you could also simply put the categories list in a shared cache, so that you don't have to reuse your activity by can create a new one, the categories list will be retrieved once and put in the cache, subsequent activity instances will just use what's in the cache. This is similar to the above, but simpler, and the cache could be used by other parts of the application.
I'd personally rather go with your approach though (with a small exception, see below), as it's the simplest/easiest. Decoupling the activity from the "screen" is also an option; the GWT Team started exploring this approach in the Expenses sample (decoupling the activity responsibility from the presenter responsibility with using MVP) without ever finishing it unfortunately.
Other than that, I don't think any best practice has really emerged for now.
†. I don't like coupling my activities with the places they're used with (I don't quite like the coupling for the goTo calls either, but haven't yet found a clean and simple alternative), so I'd rather not go with this option; and similarly, I'd not pass the place to the activity constructor and refresh method like you did, but rather extract the information out of the place and pass it to the activity (e.g. in your case, only give the category ID to the activity, not the ItemListPlace instance; I would then simply call setCategory in all cases, and not even pass the category ID to the constructor).
In my opinion,
The role of the ActivityMapper is to give you back an Activity from a Place.
The role of the ActivityManager is to start the Activity given back from the ActivityMapper and to stop the current one if different. In your case you would like to "update/refresh" the current Activity.
So I would modify the ActivityMapper so as it will allways give me back the same instance of Activity for a given type of Place. A good way to do so could be to use GIN and use the singleton scope ...in(Singleton.class) to inject your Activity.
If you do that, when changing the url, if the place stays the same (meaning your url has the same word after # and before :) so that the Type of your place stays the same, the ActivityMapper will give you back the same instance of Activity so the ActivityManager will do nothing on the Activity. Check l.126 of ActivityManager
if (currentActivity.equals(nextActivity)) {
return;
}
For me you have 2 options there. The first one, as Thomas said , is to listen to PlaceChangeEvent in your Activity. The new Place you will receive can have new parameters inside based on the new url given and you can "update/refresh" your Activity.
The second one, that I find more in line with the Activity/Place pattern is to modify the ActivityManager so that it calls an update(Place) method on the Activity when the Activity given back by the ActivityMapper is the same that the current Activity.
I haven't tried any of these solutions yet but I will soon ... I might be able to update that post at that time.
You can find more information in this article I wrote on my blog on that topic
Here is a little schema I made to help me understand the pattern, hope it will help :
I would not do any logic in my ActiviyMapper except returning an activity, by creating a new one or giving a previous one (or null). According to me, the mapper doesn't have to know about refresh() or what activities do.
If that, then the logic of 'refresh()' would be given to the activy through the place which holds a token. That token should be holding the information about either what is the state of the request (a new page, reload, an id, etc).
In the activity, first, it asks for the View, the one related to this activity (tip : a singleton given by a 'ClientFactory' is good practice), then it creates a presenter for that view, and bind them together.
Lastly, the activity will use the token from the place to provide any information about state to the presenter. And then, it adds the view in the page.
It's good to know by default, with places and activies, going to the same place doesn't do anything (no reload). But you can take care of it with token and activity-mapper easily.
Hope you'll find an adapted solution for you case. Goodluck.

MVVM setup design time services?

I'm working with the MVVM pattern + a simple ServiceLocator implementation, now to my problem how am I supposed to setup the services when the views are running in design time?
Iv tried this but it does not seem to work in VS 2010 or some thing, I know it worked on my old computer but on my new it does not. so does any one know a good alternative?
Edit: (On behalf of Merlyn Morgan-Graham)
Well what I'm trying to do is this, I have my view, ViewModel and services now the difference here is that I have 2 implementations of each service one for design time and one for run time.
for a better explanation look here.
If you want to decouple your view from your viewmodel, and your viewmodel from your model/dal (basically, if you want to use MVVM), then your view model and data model shouldn't know anything about design time. Design time only applies to the view.
This article shows a way to define your design time data via XML/XAML, so your code underneath doesn't have to know anything about it:
http://karlshifflett.wordpress.com/2009/10/21/visual-studio-2010-beta2-sample-data-project-templates/
After Edit: It turns out that you'll still have to use your view model for your existing XAML bindings to work. This will just populate the view model rather than having to create a new data model. I'm not sure, but there might be classes that allow you to use the WPF binding mechanism to take care of this... Views?
Resume Before Edit...:
As far as the solution in the article you linked first, the designer doesn't instantiate anything but your class, and the code it references. That means that assembly attributes won't be instantiated unless your view code somehow directly references them.
If you really want to couple your view models to your views during design time, and make it so that design time services are registered, then you have to place the service registration code in your view class, or a class the view class directly references.
To do that, you could use static constructors of your views to register your design time services. You could also write a static method on some other class (application?) to (conditionally) register the design time services. Then, call that method in the constructor of your views.
Or you could simply register them in the constructor for each of your views.
Basically, what you want to do is possible, but that method linked in the first article isn't. If you read farther in the comments, you'll see that his method is broken.
You may also want to question the idea of hooking your view model to your view during design time, because the MVVM pattern was made to avoid that sort of thing.
You usually don't need to access services at design-time... Typically, you don't even use your real ViewModels at design-time, you use dummy design data, as explained here. If you really need to use your real ViewModels, you can implement dummy versions of your services, and use them instead of the real services :
if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
{
// Design time
ServiceLocator.Instance.Register<IService1>(new DummyService1());
ServiceLocator.Instance.Register<IService2>(new DummyService2());
}
else
{
// Run time
ServiceLocator.Instance.Register<IService1>(new RealService1());
ServiceLocator.Instance.Register<IService2>(new RealService2());
}
Also I do agree to all who have concerns regarding the use of the service locator at design time, I do believe that this is a valid scenario in some use cases.
This is not a discussion on why/why not, this is simple the way it (almost) worked for me.
There is still a problem which I did not solve yet: this only works for one view at a time.
Create a simple bootstrapper for setting up your IoC of choice. Notice the ISupportInitialize interface.
public class Bootstrapper: ISupportInitialize
{
#region ISupportInitialize Members
public void BeginInit() { }
public void EndInit()
{
if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
Setup();
}
#endregion
public static void Setup() { SetupServiceLocator(); }
static void SetupServiceLocator()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<ConfigService>().As<IConfigService>().ExternallyOwned().SingleInstance();
IContainer container = builder.Build();
ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(container));
}
}
Use the Bootstrapper as before for runtime mode, e.g.:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Bootstrapper.Setup();
}
}
Additionally you need to add it to the application resources for design mode support:
<Application x:Class="MonitoringConfigurator.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyBootstrapperNamespace"
StartupUri="MainWindow.xaml">
<Application.Resources>
<local:Bootstrapper x:Key="Bootstrapper" />
</Application.Resources>
</Application>