使用工厂时覆盖AutoFac范围配置

时间:2015-03-11 14:48:39

标签: c# dependency-injection autofac

如何配置AutoFac,以便每次出厂时都会获得Context的新实例。 Content组件设置为InstancePerLifetimeScope(),这对我99%的使用率来说是完美的,但现在我需要对Context组件的范围进行一些额外的控制。

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

        builder.RegisterType<Box>();
        builder.RegisterType<DbContext>().InstancePerLifetimeScope();

        var container = builder.Build();

        using (var scope = container.BeginLifetimeScope())
        {
            var x = scope.Resolve<Box>();
        }

        Console.ReadKey();
    }
}

class Box
{
    public Box(DbContext.Factory factory)
    {
        factory();
        factory(); // Want this to generate a NEW instance

        Console.WriteLine("Box: {0}", GetHashCode());
    }
}

class DbContext
{
    public delegate DbContext Factory();

    public DbContext()
    {
        Console.WriteLine("Context: {0}", GetHashCode());
    }
}

显然,这是一个相当简化的代码片段。我试图解决的问题是我有大量的数据流进入服务,我正在尝试批量保存到数据库。因此,如果Box可以根据需要创建新的UOW,并将其及时发布以便及时处理,那么我会得到一个很好的清洁解决方案。

谢谢!

1 个答案:

答案 0 :(得分:3)

您可以使用Func<Owned<>>,其作用类似于小ILifetimeScope

public Box(Func<Owned<DbContext>> factory)
{
    using (Owned<DbContext> ownedDbContext = factory())
    {
        // instance1
    }
    using (Owned<DbContext> ownedDbContext = factory())
    {
        // instance2 
    }
}

您可以在Autofac文档中找到更多详细信息:Owned Instances

另一个解决方案是注入ILifetimeScope,然后创建一个子生命周期镜:

public Box(ILifetimeScope scope)
{
    using (ILifetimeScope subScope = scope.BeginLifetimeScope())
    {
        DbContext dbContext = subScope.Resolve<DbContext>();
    }
}

public Box(ILifetimeScope scope)
{
    ILifetimeScope subScope = scope.BeginLifetimeScope();
    scope.Disposer.AddInstanceForDisposal(subScope);
    DbContext dbContext = subScope.Resolve<DbContext>(); 
    // no need to dispose subScope, 
    // subScope (and dbContext) will be disposed at the same time as scope
}