Unity RegisterInstance的IDisposable对象

Tru*_*ill 9 c# dependency-injection idisposable unity-container unity2.0

Unity 2.0:

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

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

container.RegisterInstance(instance, new ExternallyControlledLifetimeManager());
Run Code Online (Sandbox Code Playgroud)

Unity文档(在了解终身经理下)指出:

使用RegisterInstance方法注册现有对象会产生与刚刚使用RegisterType注册生命周期容器相同的行为.因此,建议您在使用非默认生存期管理器时不使用RegisterInstance方法注册现有对象,但调用RegisterInstance的线程除外.

这是什么意思?

同一部分还指出:

如果使用RegisterInstance方法注册了对象的现有实例,则容器将为Resolve或ResolveAll的所有调用返回相同的实例,或者当依赖性机制将实例注入其他类时,前提是满足下列条件之一:

  • 您已指定容器控制的生命周期管理器
  • 您已使用默认生命周期管理器
  • 您正在使用不同的生命周期管理器在您注册实例的相同上下文中进行解析.

在使用RegisterInstance和ExternallyControlledLifetimeManager之后,我尝试在另一个线程中解析,并且它工作了 - 我得到了单例实例.

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

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

Lad*_*nka 5

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


And*_*ykh 2

我觉得你很好。所有每线程注释仅在您使用 PerThreadLifetimeManager(您没有使用)时才重要。MSDN 文章部分的措辞很笨拙。

这不是标准术语,但在本文中,根据上下文,它们的意思是由特定的终身管理者定义的东西。对于 PerThreadLifetimeManager,您的上下文就是您的线程。对于 HierarchicalLifetimeManager,您的上下文是容器层次结构中的特定容器。

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

附带说明一下,请确保在您仍期望容器解析实例时不要处置它们。如果这样做,您的解析请求将返回与您预期不同的实例,或者抛出异常,具体取决于容器是否可以构造您的类型。