I have an 2 regions in my silverlight application leveraging prism 4 and unity main shell view, the Authenticated region and Non-authenticated region, and a menu item.
Within the authenticated region, there are a lot more sub regions depending on the view injected into it.
On load of the application, I will be presented with the login screen "Non-authenticated region", when login, I will be presented in the Authenticated region.
When I click on the logout button on the menu, I will again be presented with the login view.
But when I login for the second time, my existing view loaded within the authenticated region is still there.
I tried the following code on logout, to remove all views from that region, but the views retrieved from the container is still the existing view..
var regions = this.RegionManager.Regions;
foreach (var region in regions)
{
if (region.Name == this.AuthenticatedRegionName)
{
开发者_如何转开发 var views = region.Views;
foreach(var view in views)
{
region.Remove(view);
}
}
}
I am actually getting some region key not found error when I call request navigate for some reason, but I think the main issue is with the container.
How can I tell unity to dispose all views?
Since you are using the ContainerControlledLifetimeManager
for the View the View will resolve to the same instance for the lifetime of the IUnityContainer
. Removing a View from a region does not in any way remove it from the IUnityContainer
since the IUnityContainer
contains a strong reference to the View.
The better approach is to not force your Views to behave as a Singleton. If you desire Singleton behavior push that behavior to either a Service or ViewModel which can remain for the life of the IUnityContainer
without any ill effects.
The View should not behave in a state aware manner; it should remain stateless and therefore forcing your View to act as a Singleton should be avoided.
If you are certain you want Singleton behavior within your view you can use the ExternallyControlledLifetimeManager
which would hold a weak reference to the View. The View would then be GC'ed once all strong references to it are removed.
I solved it by looping through the UnityContainer.Registration, and checking the LifetimeManagerType of each registration, if they are of ContainerControlledLifetimeManager and MappedToType equals to my base view model type, I create a new instance for it like so an set it to the set value on LOGOUT.
var registrations = this.UnityContainer.Registrations;
if (registrations != null)
{
foreach (var registration in registrations)
{
if (registration.LifetimeManagerType != null &&
registration.LifetimeManagerType == typeof(ContainerControlledLifetimeManager) &&
registration.MappedToType.FullName.Equals("Main.ViewModelBase"))
{
var objectType = registration.LifetimeManager.GetValue().GetType();
var newInstance = Activator.CreateInstance(objectType, new object[]{this.UnityContainer});
registration.LifetimeManager.SetValue(newInstance);
}
}
}
Not elegant but it works for now, cheers
精彩评论