可能是Unity初学者的问题:在使用Unity时,您是否仍然需要在已注入对象上实现Dispose方法?或者甚至不需要这样做(因此由Unity自动完成)?这是在Web应用程序的上下文中。
可能是Unity初学者的问题:在使用Unity时,您是否仍然需要在已注入对象上实现Dispose方法?或者甚至不需要这样做(因此由Unity自动完成)?这是在Web应用程序的上下文中。
实现IDisposable
与Unity无关。当您的类型使用非托管资源如文件时,应该实现该接口,因为这些资源不能被CLR垃圾回收。
Unity可以管理您的类型和实例的生命周期。对于这种情况,Unity提供了不同类型的LifeTimeManager来控制实例的生命周期。
只有当您使用ContainerControlledLifetimeManager
或HierarchicalLifetimeManager
注册实例时,Unity才会尊重IDisposable
接口。这意味着,当您处理Unity-Container时,它也将在上述命名LifetimeManager注册的所有实现IDisposable
接口的实例上调用Dispose
。
当您使用TransientLifetimeManager
(每次调用容器上的Resolve时都会获得一个新实例)注册实现IDisposable
接口的类型时,您需要自己调用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.");
}
}
}
}
在2018年1月11日,Unity
新增了另一个生命周期管理器ContainerControlledTransientManager
,它遵循IDisposable
接口Add container 'owned' transient lifetime manager ContainerControlledTransientManager #37
因此,需要使用
ContainerControlledTransientManager
。这个生命周期管理器与TransientLifetimeManager
相同,但如果对象实现了IDisposable
接口,它将保持对该对象的强引用,并在容器被释放时进行处理。 如果创建的对象不可处理,则容器不会维护任何对象引用,因此当该对象被释放时,GC将立即回收它。
Dispose
:如果您Resolve
一个本身依赖于IDisposable
对象的对象,那该怎么办?当您不再需要它时,您无法找到这些对象。此外,手动调用Dispose
意味着您必须确保它已经注册为TransientLifetimeManager
- 如果它在未来更改为不同的生命周期,您将处置共享/单例对象,这些对象可能正在被其他地方使用。 - Philip C