How to instantiate a new view/view-model each time it is navigated to?

Topics: Prism v4 - WPF 4
Jul 24, 2013 at 1:40 PM
Edited Jul 24, 2013 at 2:22 PM
I'm using Prism 4 navigation, and Castle Windsor. I'm a bit unclear on view lifetime, and how to instantiate a new view each time I navigate to it. I've implemented the following:-
  • Register the views/view-models with Windsor as "transient"
  • Mark the view-models with attribute "[RegionMemberLifetime(KeepAlive = false)]"
Sure enough, each time I navigate to a view using "regionManager.RequestNavigate()", the constructor gets called, confirming that a new view is instantiated each time. But what happens to the "old" views? I'm finding that they are still responding to events published from my "event aggregator" service, so am I responsible for clearing up these old/inactive views, and if so how?

Lastly, one of my views has nested regions/views - assuming I've configured these views as above, will they be destroyed when the parent view gets destroyed?
Jul 24, 2013 at 2:43 PM
For info, I've sorted the problem with the events by unsubscribing in the views' OnNavigatedFrom() method. However it makes me uneasy to think that these views aren't being destroyed for whatever reason, and are sitting around taking up memory. Am I missing something?
Jul 24, 2013 at 5:40 PM

Based on my understanding, the approach you took to solve the problem is the correct one. You need to unsubscribe when you navigate since the KeepAlive = false will only mark your ViewModel for garbage collection, but you can't control when the garbage collection occurs. For that reason, until the Garbage Collector runs, those old instances of your ViewModels will remain in memory, and that's the reason why they continue responding to events. Take into account that the Garbage Collector will remove these ViewModels as long as there are no strong references to them.

Regarding your nested regions question, in order for you to remove a view and all nested regions/views contained in it afterwards, the following attached property must be defined in your view XAML like in the following code snippet:
You can find more information about this topic in the Prism 4.1 Readme.

Hope this helps,

Federico Martinez
Jul 25, 2013 at 8:15 AM
Hi Federico, thanks for your reply.

As the views/view-models are transient, and instantiated by Castle Windsor, I guess I just have to trust Windsor to release them! I don't know if it's possible to know when a view/VM is released - I tried implementing IDisposable and putting a breakpoint in Dispose(), but I've read somewhere that Castle Windsor doesn't honour IDisposable when releasing.

Regarding the ClearChildViews attribute, I've tried this and it doesn't seem to do anything. Would you expect it to call OnNavigatedFrom() of each child view-model or is it some kind of "internal" cleanup routine?
Jul 25, 2013 at 8:11 PM

As you correctly pointed out, Castle Windsor discourages to implement IDisposable because the release policy can opt out of tracking components and therefore lose the ability to perform the proper destruction of the component. Also, take into account that Windsor may track components defined as "transient" when you Resolve their instances. In that case, you will need to Release them in order for the Garbage Collector to be able to reclaim them. In other words, you have to Release what you explicitly Resolved.

Regarding the ClearChildViews attribute, if this attribute is correctly set and you remove a view that has a nested region, Prism should automatically remove the views from that nested region. Therefore, it won't invoke the view's navigation methods. If you need to check this, you could subscribe to the CollectionChanged event of the region views collection or verify that it is empty after you remove the view containing the nested region.


Federico Martinez
Jul 26, 2013 at 8:17 AM
My understanding of Windsor is that you must release what you explicitly resolve, but you don't have to worry about releasing (say) a transient that was instantiated during dependency injection, for example.

How does this notion fit in with Prism navigation? Prism presumably instantiates a view during region navigation (and the view in turn has its view-model DI'd via the constructor), but all this is happening "under the covers", so do I need to worry about releasing transient views/view-models when they are finished with, and if so how/where would I do this?
Jul 26, 2013 at 6:06 PM

As you correctly pointed out, in Castle Windsor you only have to worry about releasing what you explicitly resolved. This means that you can be sure that, if you do this and you don't have any strong reference to your "transient" view/viewmodel, the view/viewmodel will be eventually reclaimed by the Garbage Collector.

Regarding Prism navigation, after verifying that region exists and the view is able to navigate, it creates a new instance of the view/viewmodel using the ServiceLocator, adds it to the region, and then activates it. The Service Locator will use your container to create said instances. In order to do this, the Service Locator needs to have a location provider that it could use to delegate the creation logic to the container. Assuming you have an adapter in your Windsor container configured for the Service Locator, you should check how it retrieves the instances from the container so that you can be sure if you need to explicitly release your views/viewmodels.

Hope this helps,

Federico Martinez