Unity RegisterInstance的IDisposable对象

时间:2011-03-16 19:23:10

标签: c# dependency-injection unity-container idisposable unity2.0

Unity 2.0:

默认情况下,RegisterInstance使用ContainerControlledLifetimeManager。当处置Unity容器时,它会调用实例上的Dispose(如果是IDisposable)。

在我的情况下,这不是我想要的。该实例由另一个类拥有并处置; Unity应该只注入引用。所以我用过:

container.RegisterInstance(instance, new ExternallyControlledLifetimeManager());

Unity文档(在了解终身经理下)说明:

  

使用RegisterInstance方法   注册现有对象的结果   和你一样的行为   注册了终身容器   RegisterType。因此它是   建议你不要使用   RegisterInstance方法注册一个   使用时的现有对象   非默认终身经理除外   对于其中的线程   调用了RegisterInstance。

这是什么意思?

同一部分还指出:

  

如果您注册了现有实例   使用该对象的对象   RegisterInstance方法,容器   为所有人返回相同的实例   调用Resolve或ResolveAll或何时调用   注入依赖机制   提供了其他类的实例   以下之一是真的:

     
      
  • 您已指定容器控制的生命周期管理器
  •   
  • 您已使用默认终身经理
  •   
  • 您正在解决您注册的相同环境   使用不同的实例   终身经理。
  •   

在使用带有ExternallyControlledLifetimeManager的RegisterInstance之后,我尝试在另一个线程中解析,它运行了 - 我得到了单例实例。

我的代码与“创建实例注册”部分中的示例相匹配。不过,我想确保理解背景警告。

要清楚,我总是希望Unity容器注入我注册的实例而不管线程等等。我希望Unity处理它。我这样做了吗?

2 个答案:

答案 0 :(得分:5)

请注意ExternallyControlledLifetimeManager。您仍必须在容器外部的某个位置保留对实例的引用。丢失参考后,您可能会丢失该实例,因为ExternallyControlledLifetimeManager仅保留WeakReference。如果您没有正常参考垃圾收集器可以收集您的实例。在我的博客上查看example

答案 1 :(得分:2)

我觉得你很好。所有每线程注释仅在您使用PerThreadLifetimeManager时才有意义,而您不使用它。这只是MSDN文章部分的笨拙措辞。

这不是标准术语,但在本文中,它们指的是由特定的终身经理定义的内容。对于PerThreadLifetimeManager,您的上下文就是您的线程。对于HierarchicalLifetimeManager,您的上下文是容器层次结构中的特定容器。

对于ExternallyControlledLifetimeManager,没有特定的上下文,因此您可以完全忽略相关注释。

作为旁注,请确保在您仍然希望容器解决它们时不要丢弃实例。如果这样做,您的解析请求将返回与您预期不同的实例,或者抛出异常,具体取决于容器是否可以构造您的类型。