注册代表时采用什么Autofac LifetimeScope?

时间:2017-04-19 19:34:26

标签: autofac

我无法从文档中确定这一点。

鉴于注册:

builder.RegisterType<ExampleComponent>().As<IComponent>().InstancePerLifetimeScope();

以下注册将采用什么LifetimeScope?

builder.Register(ctx =>
{
    var component = ctx.Resolve<IComponent>();
    return new SomeService(component);
}).As<ISomeService>();

注意:这只是一个例子。显然,在这种情况下,您只需解析ISomeService并允许Autofac使用IComponent依赖关系实例化SomeService实例。我有一个更复杂的注册需求,这种方法是必要的,但其细节与这个问题并不相关。

鉴于IComponent已注册为InstancePerLifetimeScope(我理解为它意味着它继承了用于直接解析此问题的作用域或用于解析此作为依赖项的组件的作用域),并且为ISomeService注册的委托将是InstancePerDependency的默认生命周期范围,我希望委托中IComponent的解析将使用生命周期范围InstancePerDependency。

这是对的吗?

1 个答案:

答案 0 :(得分:1)

当您解析ISomeService时,这将按预期完成每个依赖项,这意味着您将在每个解析时获得SomeService的新实例(通过调用委托)。

然而,调用get组件例如:

var component = ctx.Resolve<IComponent>();

将返回每个生命周期范围共享的一个组件实例(因此,如果您不创建任何子/嵌套生命周期范围,它将或多或少是一个单例)。

这是一个展示它的小例子。

首先,这是IComponent的一个简单实现:

public interface IComponent
{
    int GetId();
}

public class ExampleComponent : IComponent
{
    private static int id = 0;
    private int instanceId;

    public ExampleComponent()
    {
        this.instanceId = id;
        id++;
    }

    public int GetId()
    {
        return this.instanceId;
    }
}

然后是ISomeService:

public interface ISomeService
{
    int GetServiceID();
    int GetComponentId();
}

public class SomeService : ISomeService
{
    private static int id = 0;
    private int instanceId;


    private readonly IComponent component;

    public SomeService(IComponent component)
    {
        if (component == null)
            throw new ArgumentNullException("component");

        this.component = component;
        this.instanceId = id;
        id++;
    }

    public int GetComponentId()
    {
        return this.component.GetId();
    }

    public int GetServiceID()
    {
        return this.instanceId;
    }
}

我按照你写的那样保持注册:

    ContainerBuilder builder = new ContainerBuilder();

         builder.RegisterType<ExampleComponent>().As<IComponent>().InstancePerLifetimeScope();
         builder.Register(ctx =>
         {
             var component = ctx.Resolve<IComponent>();
             return new SomeService(component);
         }).As<ISomeService>();

         IContainer rootContainer = builder.Build();

现在让我们做点决心:

ISomeService service1 = rootContainer.Resolve<ISomeService>();
         ISomeService service2 = rootContainer.Resolve<ISomeService>();

         Console.WriteLine(string.Format("Service 1: {0} , Component : {1} ", service1.GetServiceID(), service1.GetComponentId()));
         Console.WriteLine(string.Format("Service 2: {0} , Component : {1} ", service2.GetServiceID(), service2.GetComponentId()));

你会得到:

服务1:0,组件:0 服务2:1,组件:0

由于Component由主生命周期范围共享。

当然,如果您创建子范围:

IContainer rootContainer = builder.Build();

        ILifetimeScope scope1 = rootContainer.BeginLifetimeScope();
        ILifetimeScope scope2 = rootContainer.BeginLifetimeScope();

        ISomeService service1 = scope1.Resolve<ISomeService>();
        ISomeService service2 = scope2.Resolve<ISomeService>();

        Console.WriteLine(string.Format("Service 1: {0} , Component : {1} ", service1.GetServiceID(), service1.GetComponentId()));
        Console.WriteLine(string.Format("Service 2: {0} , Component : {1} ", service2.GetServiceID(), service2.GetComponentId()));

服务1:0,组件:0 服务2:1,组件:1

在这种情况下,您有两个不同的范围,因此每个对组件的解析将提供不同的范围。