29

可能是 Unity 初学者的一个问题:在使用 Unity 时,您是否还需要在已注入的对象上实现 Dispose 方法?或者甚至不需要(所以,由 Unity 自动完成)?这是在 Web 应用程序的上下文中。

4

3 回答 3

31

实施IDisposable与 Unity 无关。当您的类型使用非托管资源(如文件)时,您应该实现该接口,这些资源不能被 CLR 垃圾收集。

Unity 可以管理您的类型和实例的生命周期。对于这种情况,Unity 提供了不同类型的 LifeTimeManager 来控制实例的生命周期。

Unity 仅在您使用或IDisposable注册它们时尊重接口。这意味着当您处置 Unity-Container 时,它还将调用所有实现上述 LifetimeManager 注册的接口的实例。ContainerControlledLifetimeManagerHierarchicalLifetimeManagerDisposeIDisposable

当您使用 注册实现IDisposable接口的类型时TransientLifetimeManager(您在容器上调用 Resolve 的每种类型都会获得一个新实例),由您来调用Dispose该实例。

于 2012-11-27T10:15:27.780 回答
9

扩展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.");
            }
        }
    }
}
于 2014-02-18T18:17:37.720 回答
0

另一个ContainerControlledTransientManager尊重的生命周期管理器于 2018 年 1 月 11 日IDisposable添加到添加容器“拥有”瞬态生命周期管理器 ContainerControlledTransientManager #37Unity

所以,ContainerControlledTransientManager是必需的。这个生命周期管理器是一样的,TransientLifetimeManager除非对象实现IDisposable它会保持对对象的强引用并在容器被释放时释放它。如果创建的对象不是一次性的,容器不会维护任何对象引用,因此当该对象被释放时,GC 将立即收集它。

于 2021-12-07T14:12:54.763 回答