Prism, ServiceLocator and Unity container hierarchy and multi-window WPF application - wpf

I want to build a WPF/Prism application where each top level window is in its own UI thread. That is fairly straight forward to do. I am using Unity as my DI container and would like to create a hierarchy of containers. In the simplest case, the root container will be at the application level and each window will have a child container. This is desirable as each window can have its own shared objects scoped by the child container.
I would like each window to have their own region manager from Prism so that I don't have any cross threading issues as each Window will have its own UI thread. I see that the Region and RegionManager use the ServiceLocator.Current singleton. This is an issue because I would like the RegionManager to use the container it is scoped to which is not possible with a static singleton. Have any of you run into this issue and how would you work around it?
Thanks!

You can have your Bootstrapper as child container and register your types there. And have your ServiceLocater in the application level which will call your Bootstrappers.
more info about; http://msdn.microsoft.com/en-us/library/ff649077.aspx

I actually needed to do the same thing, and I figured out the following solution:
Before navigating to the "child" region, do the following:
var childRegion = _childRegionManager.Regions["ChildRegion"];
_childRegion.NavigationService = _childContainer.GetExportedValue<IRegionNavigationService>();
_childRegion.NavigationService.Region = _childRegion;
This sets the correct navigation service on the child region.
Of course, childContainer should have an IRegionNavigationService in its own catalog, so that it will compose it properly.

Related

WPF Prism reloading module using IModuleManager.LoadModule

I need to display views in a Module.The Module Registers it's view using in Initialize method.
User will select module name from drop down list. First time it works using IModuleManager.LoadModule(string ModuleName). If I want to re-display the same module again(in the same region after clearing the previously displayed module) IModuleManager.LoadModule is not going to work. I dont know the views and regions contained in that Module. I know just ModuleName and I need to display it's view.
How can I do that?
Your questions is very confusing. Can you provide more information? The IRegionManager is the component to register Views to your predefined Regions. The ModuleManager is only responsible to load an assembly if I got that right.
I don't think you can Load a Module multiple times, because the second time it is loaded already. The logic for displaying views should be regulated via Services within your Modul so inside your Module should be a Method that uses the IRegionManager to register a specific View to a Region.
I don't know whether you use Unity or MEF ( or another IOC ) but you can obtain the IRegionManager within your Module via the Container.
Maybe you should watch this Tutorial series Prism Tutorial Series. It seems to me you are missing some basic principles

Bootstrapping Windsor Castle IoC in WPF application

I am used to using Windsor Castle IoC with MVC web applications so I'm a little familiar with registering components and bootstrapping the application.
I am now trying to create my first WPF application and I'm a little lost....
In a typical MVC project I would register all my components in Application_Start in the Global.asax file.
Also, in the Global.asax I would do something like this :
_container = new WindsorContainer();
var myControllerFactory = new MyControllerFactory(_container.Kernel);
ControllerBuilder.Current.SetControllerFactory(myControllerFactory);
In MyControllerFactory which inherits from DefaultControllerFactory I would resolve the Controller given to me, thus all the controllers being used would have their dependencies resolved automatically.
How could I do this in a WPF application ?
I created a class called ContainerBootstrapper that registers my components, and now I'm wondering how I use this in my MainWindow so every time I call a component, it's dependencies are resolved automatically...
Unlike MVC, WPF does not provide framework for decoupled UI development out of the box. There are several out there (such as Caliburn.Micro which implements the MVVM pattern) that sit on top of WPF and provide integration for a variety of IoC containers as well as other features you may find useful in WPF development.
Alternatively, you will need to manage the container directly. i.e. instantiate and initialise the container in App.xaml.cs or MainWindow.xaml.cs and ensure that new object construction via your container's Resolve() function. If it is a non-trivial app, you will probably want to integrate this into your app's navigation routines.

Ninject Registration with Silverlight and Prism

I am using Ninject as my bootstrapper (mainly because of convention based registration and its fluent API).
We are using Prism 4 Navigation Framework RequestNavigateAsync call to navigate from one page to the other. The API looks into the container for named instance of the object and resolve the view / viewmodel that it needs to navigate to. Here's Unity syntax for this.
Its recommened to use
container.RegisterType("InboxView"
instead of container.RegisterType("InboxView")
In Ninject, how can I get similar effect so that it gels with Navigation framework easily?
Can you help provide some code / documentation which shows how to register named instances in Ninject (that might help).
Assuming this is your syntax in Unity
var container = new UnityContainer();
container.RegisterType<object, InboxView>("InboxView");
The equivalent syntax in Ninject is
var kernel = new StandardKernel();
kernel.Bind<object>().To<InboxView>().Named("InboxView");

Prism Module Lifecycle

I have developed a silverlight prism project to replicate a memory leak. Just wondering about the lifecycle of a prism module.
If inside a module I register a view does the view get destroyed when the module is no longer in use?
Also does each module share the same dependency container (e.g. unity) or does each module have a separate one?
I have a more in depth question here,
https://stackoverflow.com/questions/4652364/memory-usage-is-suspect-when-loading-prism-modules
I am trying to understand some discrepancies with memory usage when opening and closing prism modules.
1) The point in time the view gets destroyed depends on the way you have registered the view to the container. If you didn't change the object lifecycle during registration, it will be destroyed when the GC finds it without having any object referencing it. If you explicitly specified a lifetime manager during the registration the view gets destroyed depending on the particular lifetime the manager manages. An exmaple: When you are using a Unity container and you registered the view with a ContainerControlledLifetimeManager the view gets destroyed when the container gets destroyed.
2) All modules share one container as long as you don't make a child container for each module on your own.

WPF Prism Inject same viewmodel instance into two views

So I have two separate views in a WPF Prism app. How can I inject the same instance of a ViewModel into both the views via Dependency Injection?
(I assume you are using Unity as you mentioned DI directly and are not saying "Import" or similar)
Hi,
You will have to register the ViewModel as a singleton (using a ContainerControlledLifetimeManager) in the container and have it injected as usual. This ensures that you will get the same instance whenever you request for it.
A valid approach in this scenario might be to use a named registration in case you want to get the same VM injected elsewhere, but you don't need the same instance.
This article explains how to do this.

Resources