【问题标题】:How to reset all instances in IOC Container如何重置 IOC 容器中的所有实例
【发布时间】:2013-06-07 05:43:20
【问题描述】:

我使用MVVM Light framework 制作了一个 C# WPF 应用程序。我的应用程序使用 ViewModelLocator 类在运行时定位视图模型。 ViewModelLocator 使用 SimpleIoc 类,该类也与 MVVM Light framework 一起提供。

这是我的场景: 用户登录可以使用我的应用程序。注销时,我想处置/重置/重新创建所有视图模型实例,为下一个用户提供一个干净的环境。

我尝试在ViewModelLocator 类中实现Cleanup() 方法,但它不起作用。 不工作意味着(第二个)用户看到之前登录的用户的数据。

第一次尝试:

public static void Cleanup()
{
   SimpleIoc.Default.Reset();
}

第二次尝试:

public static void Cleanup()
{
   SimpleIoc.Default.Unregister<LoginViewModel>();
   SimpleIoc.Default.Unregister<TaskViewModel>();

   SimpleIoc.Default.Register<LoginViewModel>();
   SimpleIoc.Default.Register<TaskViewModel>();
}

第三次尝试(不是我想要的,但它是一种解决方法):

public static void Cleanup()
{
   // I implemented the ICleanup interface in my viewmodels
   // The cleanup method clears all my variables eg: myCollection.clear();
   SimpleIoc.Default.GetInstance<LoginViewModel>().Cleanup();
   SimpleIoc.Default.GetInstance<TaskViewModel>().Cleanup();
}

如何重置 ViewModelLocator 类中的所有实例?如有必要,我愿意使用更高级的 Ioc Container。

【问题讨论】:

  • 第三种方法有什么问题?对象不能重复使用吗?
  • 我的构造函数中有一些逻辑可以为当前用户准备一些东西。这将不再起作用。我还必须编写大量需要维护的代码(每个视图模型的清理方法)。丢弃旧实例的方法对我来说似乎要简单得多。
  • 根据 MVVM Light 维护者,这是推荐的方法。 SimpleIoc - can it provide new instance each time required?。如果这不适合您的架构,那么切换到另一个 IOC 可能会更好。
  • 你知道其他的IOC吗?
  • 我用过Simple InjectorAutoFac。 IOC 并不难写,IOC Battle 有一个很好的比较。

标签: c# wpf inversion-of-control mvvm-light ioc-container


【解决方案1】:

SimpleIoC

我会为唯一的Key 添加一个带有私有字符串后端的公共静态属性

类似

private static string _currentKey = System.Guid.NewGuid().ToString();
public static string CurrentKey {
  get {
    return _currentKey;
  }
  private set {
    _currentKey = value;
  }
}

并使用清理方法使用当前密钥注销 VM,最后重置当前密钥(在每个应用重置阶段调用):

public static void Cleanup() {
  SimpleIoc.Default.Unregister<LoginViewModel>(CurrentKey);
  ...
  CurrentKey = System.Guid.NewGuid().ToString();
}

当调用GetInstance(...) 时,只需传入静态CurrentKey

SimpleIoc.Default.GetInstance<LoginViewModel>(ViewModelLocator.CurrentKey);

【讨论】:

  • 为我工作,但我仍然更喜欢更改 IOC 容器。尽管如此,这是一个可行的解决方案,因此是正确的答案。
  • @Joel 好吧,如果您选择将 IoC 容器更改为更精细的容器,您可以使用 Unity 为您的实例提供 ExternallyControlledLifetimeManager,这只会让 GC 垃圾收集注销后,VM 一旦没有任何东西对它有强烈的引用。您还有更多管理器来管理对象的生命周期。但是,SimpleIoC 中绝对没有任何“错误”
  • 是的,我现在使用 Unity。这无关对错,只是SimpeIoC 不能满足我的所有需求。
猜你喜欢
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-17
  • 2011-02-09
  • 1970-01-01
相关资源
最近更新 更多