关于c#:AutoFac代表工厂和终身范围

AutoFac Delegate Factories and the Lifetime Scope

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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);
        }
    }
}
}


编辑:
如果您不想使用自动生成的工厂,则可以关注代表工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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();
         }
    }
 }


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

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

这是一个示例(称为Dispose):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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

编辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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();
    }
}

那是如何工作的。