web-dev-qa-db-ja.com

Unityで破棄が必要ですか?

おそらくUnity初心者の質問:Unityを使用する場合でも、注入したオブジェクトにDisposeメソッドを実装する必要がありますか?それともこれは必要ありませんか?(つまり、Unityによって自動的に行われます)?これは、Webアプリケーションのコンテキストです。

26
hetnet

IDisposableの実装はUnityとは関係ありません。タイプがFilesなどのアンマネージリソースを使用している場合は、インターフェイスを実装する必要がありますが、CLRによってガベージコレクションすることはできません。

Unityは、タイプとインスタンスの 寿命を管理する を実行できます。この場合、Unityはインスタンスのライフタイムを制御するために異なるタイプのLifeTimeManagerを提供します。

Unityは、IDisposableまたはContainerControlledLifetimeManagerを使用してそれらを登録するときに、HierarchicalLifetimeManagerインターフェイスのみを尊重します。 Unity-Containerを破棄すると、上記のLifetimeManagerによって登録されたDisposeインターフェースを実装するすべてのインスタンスでIDisposableも呼び出されます。

IDisposableを使用してTransientLifetimeManagerインターフェースを実装するタイプを登録する場合(コンテナーでResolveを呼び出す各タイプに新しいインスタンスを取得します)、インスタンスでDisposeを呼び出すのはユーザー次第です。

24
Jehof

Jehofの発言 を拡張するために、ContainerControlledLifetimeManagerHierarchicalLifetimeManagerは、サポートされている場合、クラスで.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.");
            }
        }
    }
}
7