Подтвердить что ты не робот

Устранение необходимости в единстве?

Возможно, вопрос начинающего Unity: при использовании Unity вам все равно нужно реализовать методы Dispose для объектов, которые вы ввели? Или даже это не нужно (так, сделанное автоматически Unity)? Это относится к веб-приложению.

4b9b3361

Ответ 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.");
            }
        }
    }
}