おそらくUnity初心者の質問:Unityを使用する場合でも、注入したオブジェクトにDisposeメソッドを実装する必要がありますか?それともこれは必要ありませんか?(つまり、Unityによって自動的に行われます)?これは、Webアプリケーションのコンテキストです。
IDisposable
の実装はUnityとは関係ありません。タイプがFilesなどのアンマネージリソースを使用している場合は、インターフェイスを実装する必要がありますが、CLRによってガベージコレクションすることはできません。
Unityは、タイプとインスタンスの 寿命を管理する を実行できます。この場合、Unityはインスタンスのライフタイムを制御するために異なるタイプのLifeTimeManagerを提供します。
Unityは、IDisposable
またはContainerControlledLifetimeManager
を使用してそれらを登録するときに、HierarchicalLifetimeManager
インターフェイスのみを尊重します。 Unity-Containerを破棄すると、上記のLifetimeManagerによって登録された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.");
}
}
}
}