开发者

Clear all regions/views on Prism 4 (Silverlight) Logout

开发者 https://www.devze.com 2023-02-12 20:47 出处:网络
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.

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

0

精彩评论

暂无评论...
验证码 换一张
取 消