unity container - ¿Se necesita disponer en la unidad?
unity-container dispose (2)
Probablemente la pregunta de un principiante de Unity: cuando use Unity, ¿todavía necesitaría implementar los métodos de Dispose en los objetos que ha inyectado? ¿O incluso esto no es necesario (entonces, hecho automáticamente por Unity)? Esto está en el contexto de una aplicación web.
Para ampliar lo que dijo Jehof , ContainerControlledLifetimeManager
y HierarchicalLifetimeManager
llamarán a .Dispose()
en la clase si lo admite. Sin embargo, un hecho interesante es que solo la implementación concreta necesita implementar IDisposable
, la interfaz que está asignando no lo hace. Aquí hay un programa de ejemplo simple para demostrar.
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.");
}
}
}
}
Implementar IDisposable
no tiene nada que ver con Unity. Debe implementar la interfaz cuando su tipo esté utilizando recursos no administrados, como Archivos, que CLR no puede recolectar la basura.
Unity puede administrar la vida útil de sus tipos e instancias. Para este caso, Unity proporciona diferentes tipos de LifeTimeManager para controlar la vida útil de sus instancias.
Unity solo respeta la interfaz IDisposable
cuando los registra utilizando ContainerControlledLifetimeManager
o HierarchicalLifetimeManager
. Eso significa que cuando desecha Unity-Container también llamará a Dispose
en todas las instancias que implementan la interfaz IDisposable
registrada por el LifetimeManager mencionado anteriormente.
Cuando se registran tipos que implementan la interfaz IDisposable
utilizando TransientLifetimeManager
(obtiene una nueva instancia para cada tipo que llama Resolver en el contenedor), usted Dispose
llamar a Dispose
en la instancia.