Unity RegisterInstance的IDisposable对象

9

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处理它。我做得对吗?

1
相关链接:https://dev59.com/rm435IYBdhLWcg3w7kwK - Mark Seemann
2个回答

5

请注意使用ExternallyControlledLifetimeManager。你必须在容器外部仍然持有实例的引用。一旦失去了引用,就可能会失去实例,因为ExternallyControlledLifetimeManager只持有WeakReference。如果没有正常的引用,垃圾回收器可能会清除你的实例。请参考我博客上的示例


我希望我能接受两个答案。@zespri特别回答了我的问题,但是你的博客文章也很棒。 - TrueWill

2

我认为你很棒。如果你没有使用PerThreadLifetimeManager,那么每个线程的注释都不重要。MSDN文章部分只是措辞笨拙而已。

这不是一个标准术语,但在本文中,通过上下文可以看出他们指的是由特定生命周期管理器定义的东西。对于PerThreadLifetimeManager,您的上下文就是您的线程。对于HierarchicalLifetimeManager,您的上下文是容器层次结构中的特定容器。

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

顺便提一下,请确保在您仍然希望容器解析它们时不要处置您的实例。如果这样做,您的解析请求将返回与您预期不同的实例,或者根据容器是否能够构造您的类型而抛出异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接