代码之家  ›  专栏  ›  技术社区  ›  Antoine V

MVVM Light SimpleIOC注销实例失败

  •  0
  • Antoine V  · 技术社区  · 7 年前

    我在用mvvm light做一个wpf项目。此应用程序在系统托盘上运行,并生成一个与ViewModel关联的窗口。

    当用户关闭窗口时,我有一个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
            }
    }
    

    我试图通过此代码释放实例。我确信我传递了正确的唯一密钥

    SimpleIoc.Default.Unregister(uniqueKey);
    

    第二次尝试没有效果。

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

    但当我检查时,它总是在那里。

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

    问题是:如何释放实例?

    2 回复  |  直到 7 年前
        1
  •  1
  •   mm8    7 年前

    问题是:如何释放实例?

    如果您像这样注册类型:

    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);
    
        2
  •  0
  •   Antoine V    7 年前

    这行代码会产生问题,因为它希望 准确的 类型,实例的键不足以让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(实例的唯一密钥);

    因此,要更新ViewModelLocator类:

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