2017-04-19 64 views
0

我無法從文檔中確定這一點。註冊委託時假定Autofac LifetimeScope是什麼?

鑑於登記:

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。

這是正確的嗎?

+0

如果未指定生命週期範圍,則註冊默認爲「瞬態」。請參閱http://docs.autofac.org/en/latest/lifetime/instance-scope.html#instance-per-dependency – Amy

+0

是的,「瞬態」範圍在Autofac說法中被稱爲「InstancePerDependency」。這是所述的默認行爲。問題是,儘管委託本身被註冊爲InstancePerDependency(即瞬態),但這意味着每次解析ISomeService時代理都會運行。問題是代理中的Resolve是解析具有InstancePerDependency的生命週期範圍的IComponent還是作爲其他範圍。 –

+0

啊我看到了,我誤解了它似乎的問題。 – Amy

回答

0

當您解析ISomeService時,將根據預期完成每個依賴項,這意味着您將在每次解析(通過調用委託)上獲得一個新的SomeService實例。

然而,調用get組件如:

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

將返回每一生範圍共享組件的一個實例(所以如果你沒有創建任何孩子/嵌套的壽命範圍(S),這將是或多或少是一個單身人士)。

下面是一個小例子來演示它。

首先這裏是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

由於組件由主壽命範圍共享。

現在當然,如果你創建子作用域:

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

在這種情況下,你有2個不同的範圍,所以每個解決方案組件將提供一個不同的解決方案。