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处理它。我这样做了吗?
答案 0 :(得分:5)
请注意ExternallyControlledLifetimeManager
。您仍必须在容器外部的某个位置保留对实例的引用。丢失参考后,您可能会丢失该实例,因为ExternallyControlledLifetimeManager
仅保留WeakReference
。如果您没有正常参考垃圾收集器可以收集您的实例。在我的博客上查看example。
答案 1 :(得分:2)
我觉得你很好。所有每线程注释仅在您使用PerThreadLifetimeManager时才有意义,而您不使用它。这只是MSDN文章部分的笨拙措辞。
这不是标准术语,但在本文中,它们指的是由特定的终身经理定义的内容。对于PerThreadLifetimeManager,您的上下文就是您的线程。对于HierarchicalLifetimeManager,您的上下文是容器层次结构中的特定容器。
对于ExternallyControlledLifetimeManager,没有特定的上下文,因此您可以完全忽略相关注释。
作为旁注,请确保在您仍然希望容器解决它们时不要丢弃实例。如果这样做,您的解析请求将返回与您预期不同的实例,或者抛出异常,具体取决于容器是否可以构造您的类型。