AutoFac代表工厂和终身范围

时间:2016-04-21 11:55:01

标签: c# autofac

我在我的应用程序中使用委托工厂。这是因为我使用AutoFac创建的组件使用需要一些Parameter的Service类。

我想做的下一件事就是关心这些服务是否正确清理,并使用AutoFacs生命周期范围机制释放资源。但问题是,当我使用委托工厂创建组件时,它们似乎不会被放入生命周期范围,并且在处置生命周期范围后不会调用Dispose。

我想避免使用通用的Owned<>因为我不想将我的应用程序绑定到特定的IOC。

http://nblumhardt.com/2011/01/an-autofac-lifetime-primer/中,解释了委托工厂创建的组件与委托工厂处于相同的生命周期范围。

我写了一个小程序来证明这一点。在本程序中,我希望调用Dispose函数。不幸的是,这并没有发生。我想念这里吗?下面的代码有什么问题吗?如何确保代表工厂生产的组件进入代表工厂的生命周期范围?

using Autofac;
using Autofac.Core;
using System;

namespace FactoryTest
{
class Component : IDisposable
{
    public Component(int i) { }

    public void Dispose()
    {
        throw new NotImplementedException();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var builder = new ContainerBuilder();

        builder.Register<Func<int, Component>>(c => (x) =>
        {
            // code that is important and that should run
            // inside the delegate factory.
            return new Component(x);
            });

        IContainer root = builder.Build();

        using (ILifetimeScope lf = root.BeginLifetimeScope())
        {
            Func<int, Component> compDelegatefac = lf.Resolve<Func<int, Component>>();
            Component cmp = compDelegatefac(2);
        }
    }
}
}

2 个答案:

答案 0 :(得分:1)

修改 如果您不想使用自动生成的工厂,可以关注Delegate Factories

namespace FactoryTest
{
    class Component : IDisposable
    {
        public delegate Component Factory(int i);
        public Component(int i) { Console.WriteLine(i); }

        public void Dispose()
        {
            Console.WriteLine("Component disposed");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
           var builder = new ContainerBuilder();

            builder.RegisterType<Component>().AsSelf();

            IContainer root = builder.Build();

            using (ILifetimeScope lf = root.BeginLifetimeScope())
            {
                var compDelegatefac = lf.Resolve<Component.Factory>();
                Component cmp = compDelegatefac(2);
            }
            GC.Collect();

            Console.Read();
         }
    }
 }

答案 1 :(得分:0)

在您的示例中,Lifetime Scope效果很好。

在您的代码中,您为代表注册工厂。这意味着它会处置Func<int, Component>的对象,但不会处理Component的对象(因为它是由Func创建的,而不是Autofac创建的。)

这是一个例子(调用Dispose):

void Main()
{
    var builder = new ContainerBuilder();

    builder.Register<Component>(c=>new Component(123));

    IContainer root = builder.Build();

    using (ILifetimeScope lf = root.BeginLifetimeScope())
    {
        var comp = lf.Resolve<Component>();     
    }
}

class Component : IDisposable
{
    public Component(int i) { }

    public void Dispose()
    {
        throw new NotImplementedException();
    }
}

在此示例中,它创建了Component的实例,然后(一旦LifetimeScope结束)就会调用Dispose

编辑:

void Main()
{
    var builder = new ContainerBuilder();

    builder.Register<Component>(c => new Component(123));
    builder.RegisterType<ComponentUser>().AsSelf();

    IContainer root = builder.Build();

    using (ILifetimeScope lf = root.BeginLifetimeScope())
    {
        var comp = lf.Resolve<ComponentUser>();
    }
}

class ComponentUser
{
    Component Component { get; set;}

    public ComponentUser(Func<Component> func) 
    {
        Component = func();
    }
}

class Component : IDisposable
{
    public Component(int i) { }

    public void Dispose()
    {
        throw new NotImplementedException();
    }
}

它是如何运作的。