如何为我的所有ViewModel强制执行Cleanup() [英] How to force Cleanup() for all my ViewModels

查看:224
本文介绍了如何为我的所有ViewModel强制执行Cleanup()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的ViewModel实例化资源,该资源在程序退出时必须释放.

My ViewModel instantiate resource that must be released when the program exits.

public class MainViewModel : ViewModelBase
{
    LocalServer Server { get; set; }
    Resource MyResorce { get; set; }

    public MainViewModel(LocalServer server)
    {
        this.Server = server;
        MyResource = new Resource();
    }

    public override void Cleanup()
    {
        if (MyResource != null)
            MyResource.Close();

        MyResource = null;
        base.Cleanup();
    }
}

这在ViewModelLocator中

public class ViewModelLocator
{
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        SimpleIoc.Default.Register<MainViewModel>();
    }

    public MainViewModel MainVM
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }

    public static void Cleanup()
    {
        // Wrong!! The collection is empty!
        foreach (ViewModelBase vm in ServiceLocator.Current.GetAllInstances<ViewModelBase>() )
            vm.Cleanup();

        SimpleIoc.Default.Unregister<MainViewModel>();

        Messenger.Reset();
    }
}

但是我注意到ServiceLocator.Current.GetAllInstances<MainViewModel>(),返回给定ViewModel的所有实例,但是如果我像本示例一样询问ServiceLocator.Current.GetAllInstances<ViewModelBase>(),它将返回一个空集合!

But I noticed that ServiceLocator.Current.GetAllInstances<MainViewModel>(), returns all instances of a given ViewModel but if I ask ServiceLocator.Current.GetAllInstances<ViewModelBase>() like in this example it returns an empty collection!!

因此,是否可以仅使用一个foreach来为我的所有ViewModel调用CleanUp()?

So, it's possible call CleanUp() for all my ViewModel using only one foreach?

非常感谢.

推荐答案

您将无法一次性完成此操作.原因如下:

You won't be able to do this in one go. Here's why:

内部,SimpleIoc对象包含一个实例字典:

Internally, the SimpleIoc object contains a dictionary of instances:

Dictionary<Type, Dictionary<string, object>> _instancesReDictionary<Type, Dictionary<string, object>> _instancesRegistrygistry

调用GetAllInstances时,实际上发生的是:

When you call GetAllInstances what's actually happening under the hood is:

public IEnumerable<TService> GetAllInstances<TService>()
        {
            var serviceType = typeof(TService);
            return GetAllInstances(serviceType)
                .Select(instance => (TService)instance);
        }

依次调用:

public IEnumerable<object> GetAllInstances(Type serviceType)
        {
            lock (_factories)
            {
                if (_factories.ContainsKey(serviceType))
                {
                    foreach (var factory in _factories[serviceType])
                    {
                        GetInstance(serviceType, factory.Key);
                    }
                }
            }

            if (_instancesRegistry.ContainsKey(serviceType))
            {
                return _instancesRegistry[serviceType].Values;
            }


            return new List<object>();
        }

基本上,它所做的就是检查您的类型是否存在于一个或多个字典中.这是直接比较,因此不考虑对象A是否从对象B继承.

Basically, all that it's doing is checking to see if your type exists in one or more dictionaries. It's a straight comparison so whether an object A inherits from object B isn't taken into account.

您可以做的事,需要更多的努力,但会做您想做的,就是使用Messenger向所有订阅的视图模型发送清理"消息:

What you could do, which requires more effort, but will do what you want, is use the Messenger to send a "Cleanup" message to all of your subscribing viewmodels:

ViewModelLocator:

ViewModelLocator:

 public static void Cleanup()
    {

        Messenger.Default.Send<CleanUp>(new CleanUp());
    }

ViewModel:

ViewModel:

public class MainViewModel : ViewModelBase
{
    public MainViewModel(LocalServer server)
    {
        this.Server = server;
        Messenger.Default.Register<CleanUp>(this,CallCleanUp);
    }
private void CallCleanUp()
{
    CleanUp();
}

这将起作用.如果要使其自动化,请创建一个从ViewModelBase继承的类,该类具有这种逻辑,并使您所有其他ViewModel都从该类继承,而不是从ViewModelBase继承.

This will work. If you want to make it automatic then create a class that inherits from ViewModelBase that has this logic in it and have all you other viewmodels inherit from this class instead of ViewModelBase.

这篇关于如何为我的所有ViewModel强制执行Cleanup()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆