1
votes

I'm working on a WPF project with MVVM Light. This application runs on the system tray and generates a Windows with a ViewModel associated.

When the user closes Windows, I have a ViewModelLocator to release his instance ViewModel associated. There are multi-instances ViewModel at the same time, I can't remove all instance, just the one associated with closed Window

public class ViewModelLocator
    {
        public ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

            SimpleIoc.Default.Register<CollectorViewModel>();

        public static T GetNewInstance<T>(string uniqueKey)
        {
            var model =  ServiceLocator.Current.GetInstance<T>(uniqueKey);
            return model;
        }

        public static T GetInstance<T>()
        {
            return ServiceLocator.Current.GetInstance<T>();
        }       

        public static void Cleanup(string uniqueKey)
        {
            SimpleIoc.Default.Unregister(uniqueKey);
        }
    }


public class CollectorViewModel
{
        ~CollectorViewModel()
        {
             //relase some resources
        }
}

I tried to release the instance by this code. I'm sure that I passed correct uniqueKey for the instance

SimpleIoc.Default.Unregister(uniqueKey);

2nd try doesn't have the effect.

SimpleIoc.Default.Unregister<CollectorViewModel>(myInstance); 

But when I check, it's always there.

SimpleIoc.Default.GetAllInstances(typeof(CollectorViewModel));

The question: How to release the instance?

2

2 Answers

1
votes

The question: How to release the instance?

If you register the type like this:

SimpleIoc.Default.Register<CollectorViewModel>();

...you unregister it like this, i.e without any key:

SimpleIoc.Default.Unregister<CollectorViewModel>();

This works as expected:

ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

SimpleIoc.Default.Register<CollectorViewModel>();
Debug.Assert(SimpleIoc.Default.GetAllInstances<CollectorViewModel>().Count() == 1);
SimpleIoc.Default.Unregister<CollectorViewModel>();
Debug.Assert(SimpleIoc.Default.GetAllInstances<CollectorViewModel>().Count() == 0);

If you get an instance with a key like this:

var instance = ServiceLocator.Current.GetInstance<CollectorViewModel>("xyz");

...you unregister this instance like this:

SimpleIoc.Default.Unregister<CollectorViewModel>("xyz");

This also works as expected:

ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

SimpleIoc.Default.Register<CollectorViewModel>();
Debug.Assert(SimpleIoc.Default.GetAllInstances<CollectorViewModel>().Count() == 1);
var instance = ServiceLocator.Current.GetInstance<CollectorViewModel>("xyz");
Debug.Assert(SimpleIoc.Default.GetAllInstances<CollectorViewModel>().Count() ==2);
SimpleIoc.Default.Unregister<CollectorViewModel>("xyz");
Debug.Assert(SimpleIoc.Default.GetAllInstances<CollectorViewModel>().Count() == 1);
0
votes

This line code creates the problem because it wants to a exact type, a key of the instance isn't enough for SimpleIoc to find the instance.

SimpleIoc.Default.Unregister(uniqueKey);

For example, in my project,

public class A

public class B: A

if you want to release an instance of B, you must do:

SimpleIoc.Default.Unregister<B>(unique_key_of_instance_B);

It can't work even you use class A

SimpleIoc.Default.Unregister(unique_key_of_instance_B);

So, to update ViewModelLocator class:

public static void Cleanup<T>(string uniqueKey) where T:class
{
      SimpleIoc.Default.Unregister<T>(uniqueKey);
}