我知道类似的问题已经被问了多次(例如:这里,这里,这里和这里),但这些都是针对早期版本的Unity,答案取决于使用的
文档说:
我尝试在代码中手动处理解析的实例,并且我发现另一个问题。我无法清除该实例。Lifetime Manager的RemoveValue为空 - 一旦创建了实例,就无法将其从线程静态字典中删除(我还怀疑TearDown方法什么都不做)。因此,如果在释放实例后调用Resolve,则会获得已处理的实例。我认为,在使用此生命周期管理器与线程池中的线程时,这可能是相当大的问题。
如何正确使用此生命周期管理器?
此外,这种实现经常在自定义生命周期管理器中重复使用,例如PerCallContext、PerHttpRequest、PerAspNetSession、PerWcfCall等。只替换了线程静态字典中的某些其他结构。
此外,我是否正确理解处理可处理对象取决于生命周期管理器?因此,应用程序代码依赖于所使用的生命周期管理器。
我读到在其他IoC容器中,临时处理可处理对象是由子容器处理的,但我没有找到Unity的示例 - 它可能可以通过本地范围的子容器和HiearchicalLifetimeManager来处理,但我不确定如何做到这一点。
LifetimeManager
类。文档说:
好的,听起来不错,所以我决定查看内置生命周期管理器的实现。我的结论是:Unity使用从 LifetimeManager 基类继承的特定类型(统称为生命周期管理器)来控制它存储对象实例的引用以及容器如何处理这些实例的释放。
TransientLifetimeManager
- 不处理释放。容器只解析实例,而不跟踪它。调用代码负责处理实例的释放。ContainerControlledLifetimeManager
- 在生命周期管理器被释放时(即在容器被释放时)释放实例。提供在层次结构中所有容器之间共享的单例实例。HierarchicalLifetimeManager
- 派生自ContainerControlledLifetimeManager
的行为。它为层次结构(子容器)中的每个容器提供“单例”实例。ExternallyControlledLifetimeManager
- 不处理释放。这是正确的行为,因为容器不是实例的所有者。PerResolveLifetimeManager
- 不处理释放。通常与TransientLifetimeManager
相同,但在解析整个对象图时允许重用实例进行依赖注入。PerThreadLifetimeManager
- 不处理释放,如MSDN中所述。 谁负责释放?
PerThreadLifetimeManager
的实现是:public class PerThreadLifetimeManager : LifetimeManager
{
private readonly Guid key = Guid.NewGuid();
[ThreadStatic]
private static Dictionary<Guid, object> values;
private static void EnsureValues()
{
if (values == null)
{
values = new Dictionary<Guid, object>();
}
}
public override object GetValue()
{
object result;
EnsureValues();
values.TryGetValue(this.key, out result);
return result;
}
public override void RemoveValue()
{ }
public override void SetValue(object newValue)
{
EnsureValues();
values[this.key] = newValue;
}
}
因此,释放容器不会释放使用此生存期管理器创建的可处理实例。线程完成也不会释放这些实例。那么谁负责释放实例?我尝试在代码中手动处理解析的实例,并且我发现另一个问题。我无法清除该实例。Lifetime Manager的RemoveValue为空 - 一旦创建了实例,就无法将其从线程静态字典中删除(我还怀疑TearDown方法什么都不做)。因此,如果在释放实例后调用Resolve,则会获得已处理的实例。我认为,在使用此生命周期管理器与线程池中的线程时,这可能是相当大的问题。
如何正确使用此生命周期管理器?
此外,这种实现经常在自定义生命周期管理器中重复使用,例如PerCallContext、PerHttpRequest、PerAspNetSession、PerWcfCall等。只替换了线程静态字典中的某些其他结构。
此外,我是否正确理解处理可处理对象取决于生命周期管理器?因此,应用程序代码依赖于所使用的生命周期管理器。
我读到在其他IoC容器中,临时处理可处理对象是由子容器处理的,但我没有找到Unity的示例 - 它可能可以通过本地范围的子容器和HiearchicalLifetimeManager来处理,但我不确定如何做到这一点。
UnityContainer
将在您处理它时抛出StackOverflowException。您需要使用ExternallyControlledLifetimeManager
来防止容器尝试调用其自己的Dispose方法。 - Richard DingwallIUnityContainer
接口了。 - BrainSlugs83