MVVM Light SimpleIoc Отменить регистрацию не удалось - PullRequest
0 голосов
/ 05 июля 2018

Я работаю над проектом WPF с MVVM Light. Это приложение запускается в системном трее и генерирует Windows с ассоциированной ViewModel.

Когда пользователь закрывает Windows, у меня есть ViewModelLocator, чтобы освободить его экземпляр ViewModel, связанный. Есть несколько экземпляров ViewModel одновременно, я не могу удалить весь экземпляр, только тот, который связан с закрытым окном

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
        }
}

Я пытался освободить экземпляр по этому коду. Я уверен, что передал правильный uniqueKey для экземпляра

SimpleIoc.Default.Unregister(uniqueKey);

2-я попытка не дает эффекта.

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

Но когда я проверяю, он всегда там.

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

Вопрос: как выпустить экземпляр?

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

Этот строковый код создает проблему, потому что ему нужен тип точный , ключ экземпляра не достаточен для SimpleIoc, чтобы найти экземпляр.

SimpleIoc.Default.Unregister(uniqueKey);

Например, в моем проекте,

public class A

public class B: A

если вы хотите выпустить экземпляр B, вы должны сделать:

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

Это не может работать, даже если вы используете класс A

SimpleIoc.Default.Unregister (unique_key_of_instance_B);

Итак, чтобы обновить класс ViewModelLocator:

public static void Cleanup<T>(string uniqueKey) where T:class
{
      SimpleIoc.Default.Unregister<T>(uniqueKey);
}
0 голосов
/ 05 июля 2018

Вопрос: как освободить экземпляр?

Если вы зарегистрируете тип следующим образом:

SimpleIoc.Default.Register<CollectorViewModel>();

... вы отменяете регистрацию таким образом, т.е. без ключа:

SimpleIoc.Default.Unregister<CollectorViewModel>();

Это работает как ожидалось:

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);

Если вы получите экземпляр с ключом, подобным этому:

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

... вы отменили регистрацию этого экземпляра следующим образом:

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

Это также работает как ожидалось:

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);
...