1
votes

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?

2
Have you defined a given view as ContainerControlledLifetime by chance? Region.Remove should suffice in removing the View form the given region. Calling Resolve on the Container for the given view type should provide a new instance unless you have a lifetime manager in place. - Aaron McIver
Thx for the reply, I think it does make sense, yes, a few of my screens are containerControlledLifetime (singletons)...how can I reset/clear the lifetime manager? - Joshscorp
Added answer which addresses your problem; provides different approach - Aaron McIver

2 Answers

1
votes

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.

1
votes

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