可能是 Unity 初学者的一个问题:在使用 Unity 时,您是否还需要在已注入的对象上实现 Dispose 方法?或者甚至不需要(所以,由 Unity 自动完成)?这是在 Web 应用程序的上下文中。
3 回答
实施IDisposable
与 Unity 无关。当您的类型使用非托管资源(如文件)时,您应该实现该接口,这些资源不能被 CLR 垃圾收集。
Unity 可以管理您的类型和实例的生命周期。对于这种情况,Unity 提供了不同类型的 LifeTimeManager 来控制实例的生命周期。
Unity 仅在您使用或IDisposable
注册它们时尊重接口。这意味着当您处置 Unity-Container 时,它还将调用所有实现上述 LifetimeManager 注册的接口的实例。ContainerControlledLifetimeManager
HierarchicalLifetimeManager
Dispose
IDisposable
当您使用 注册实现IDisposable
接口的类型时TransientLifetimeManager
(您在容器上调用 Resolve 的每种类型都会获得一个新实例),由您来调用Dispose
该实例。
扩展Jehof 所说的内容,如果它支持ContainerControlledLifetimeManager
,HierarchicalLifetimeManager
两者都会调用该类。.Dispose()
然而,一个有趣的事实是只有具体的实现需要实现IDisposable
,而你正在映射的接口不需要。这是一个简单的示例程序来演示。
using System;
using System.Threading;
using Microsoft.Practices.Unity;
namespace ConsoleApplication
{
internal class Program
{
private interface IFoo
{
}
private class Foo : IFoo, IDisposable
{
public Foo()
{
Console.WriteLine("Foo Created");
}
public void Dispose()
{
Console.WriteLine("Foo.Dispose() called");
}
}
private class Bar
{
public Bar(IFoo foo)
{
}
}
private static void Main()
{
LifetimeManager manager;
Console.WriteLine("Choose a lifetime manager to test:");
Console.WriteLine(" 1: ContainerControlledLifetimeManager");
Console.WriteLine(" 2: ExternallyControlledLifetimeManager");
Console.WriteLine(" 3: HierarchicalLifetimeManager");
Console.WriteLine(" 4: PerThreadLifetimeManager");
Console.WriteLine(" 5: TransientLifetimeManager");
int choice = int.Parse(Console.ReadLine());
switch (choice)
{
case 1:
manager = new ContainerControlledLifetimeManager();
break;
case 2:
manager = new ExternallyControlledLifetimeManager();
break;
case 3:
manager = new HierarchicalLifetimeManager();
break;
case 4:
manager = new PerThreadLifetimeManager();
break;
case 5:
manager = new TransientLifetimeManager();
break;
default:
return;
}
Console.WriteLine(manager.ToString());
//Use a thread to test PerThreadLifetimeManager's Dispose actions.
var thread = new Thread(() => PerformTest(manager));
thread.Start();
thread.Join();
Console.WriteLine("Press enter to exit...");
Console.ReadLine();
}
private static void PerformTest(LifetimeManager manager)
{
Console.WriteLine("Pre container creation");
using (IUnityContainer container = new UnityContainer())
{
Console.WriteLine("Pre type regrestration");
container.RegisterType<IFoo, Foo>(manager);
Console.WriteLine("Pre bar1 resolve");
var bar1 = container.Resolve<Bar>();
Console.WriteLine("Pre bar2 resolve");
var bar2 = container.Resolve<Bar>();
Console.WriteLine("Leaving container scope.");
}
}
}
}
另一个ContainerControlledTransientManager
尊重的生命周期管理器于 2018 年 1 月 11 日IDisposable
添加到添加容器“拥有”瞬态生命周期管理器 ContainerControlledTransientManager #37Unity
所以,
ContainerControlledTransientManager
是必需的。这个生命周期管理器是一样的,TransientLifetimeManager
除非对象实现IDisposable
它会保持对对象的强引用并在容器被释放时释放它。如果创建的对象不是一次性的,容器不会维护任何对象引用,因此当该对象被释放时,GC 将立即收集它。