我的ViewModel实例化了程序退出时必须释放的资源。
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();
}
}
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>()
它会返回一个空集合!!
那么,可以只使用一个foreach为我的所有ViewModel调用CleanUp()吗?
非常感谢。
答案 0 :(得分:9)
您将无法一次性完成此操作。原因如下:
在内部,SimpleIoc对象包含实例字典:
Dictionary<Type, Dictionary<string, object>> _instancesReDictionary<Type, Dictionary<string, object>> _instancesRegistrygistry
当您致电GetAllInstances时,实际发生的事情是:
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.
你可以做什么,这需要更多的努力,但会做你想要的,是使用Messenger向你的所有订阅视图模型发送“清理”消息:
ViewModelLocator:
public static void Cleanup()
{
Messenger.Default.Send<CleanUp>(new CleanUp());
}
视图模型:
public class MainViewModel : ViewModelBase
{
public MainViewModel(LocalServer server)
{
this.Server = server;
Messenger.Default.Register<CleanUp>(this,CallCleanUp);
}
private void CallCleanUp()
{
CleanUp();
}
这会奏效。如果你想让它自动化,那么创建一个继承自ViewModelBase的类,其中包含这个逻辑,让你所有其他的视图模型继承自这个类,而不是ViewModelBase。