Возможно, вопрос начинающего Unity: при использовании Unity вам все равно нужно реализовать методы Dispose для объектов, которые вы ввели? Или даже это не нужно (так, сделанное автоматически Unity)? Это относится к веб-приложению.
Устранение необходимости в единстве?
Ответ 1
Реализация IDisposable
не имеет ничего общего с Unity. Вы должны реализовать интерфейс, когда ваш тип использует неуправляемые ресурсы, любит файлы, которые не могут быть мусором, собранным CLR.
Unity может управлять временем жизни ваших типов и экземпляров. В этом случае Unity предоставляет различные типы LifeTimeManager для управления временем жизни ваших экземпляров.
Единство уважает только интерфейс IDisposable
, когда вы регистрируете их с помощью ContainerControlledLifetimeManager
или HierarchicalLifetimeManager
. Если вы удалите Unity-Container, он также вызовет Dispose
для всех экземпляров, реализующих интерфейс IDisposable
, зарегистрированный указанным выше LifetimeManager.
Когда вы регистрируете типы, реализующие интерфейс IDisposable
, используя TransientLifetimeManager
(вы получаете новые экземпляры каждого типа, который вы вызываете "Разрешить в контейнере" ), вам нужно называть Dispose
в экземпляре.
Ответ 2
Чтобы продлить на то, что сказал 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 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.");
}
}
}
}