2013-10-01 37 views
1

我想評估Autofac的範圍,據我所知,當一個實例已被聲明爲InstancePerLifetimeScope,然後在使用(container.BeginLifetimeScope())塊內,我們應該得到同樣的例子。但在另一個方面,我們應該得到一個不同的實例。但是我的代碼(在linqpad中)給了我相同的實例。然而,溫莎的生活方式卻起到了我應該的作用。Autofac LifetimeScope與BeginLifetimeScope不工作

代碼:

static IContainer glkernel; 
void Main() 
{ 
    var builder = new ContainerBuilder(); 
    builder.RegisterType<Controller>(); 
    builder.RegisterType<A>().As<IInterface>().InstancePerLifetimeScope(); 
    glkernel = builder.Build(); 

    using (glkernel.BeginLifetimeScope()){ 
    Controller c1 = glkernel.Resolve<Controller>(); 
    c1.GetA();//should get instance 1 
    c1.GetA();//should get instance 1 
    } 

    using (glkernel.BeginLifetimeScope()){ 
    Controller d = glkernel.Resolve<Controller>(); 
    d.GetA();//should get instance 2 
    d.GetA();//should get instance 2 
    } 
} 

public interface IInterface 
{ 
    void DoWork(string s); 
} 

public class A : IInterface 
{ 
    public A() 
    { 
    ID = "AAA-"+Guid.NewGuid().ToString().Substring(1,4); 
    } 
    public string ID { get; set; } 
    public string Name { get; set; } 
    public void DoWork(string s) 
    { 
    Display(ID,"working...."+s); 
    } 
} 

public static void Display(string id, string mesg) 
{ 
    mesg.Dump(id); 
} 

public class Controller 
{ 
    public Controller() 
    { 
    ("controller ins").Dump(); 
    } 

    public void GetA() 
    { 
    //IInterface a = _kernel.Resolve<IInterface>(); 
    foreach(IInterface a in glkernel.Resolve<IEnumerable<IInterface>>()) 
    { 
     a.DoWork("from A"); 
    } 
    } 
} 

輸出是:

controller ins 

AAA-04a0 
working....from A 

AAA-04a0 
working....from A 

controller ins 

AAA-04a0 
working....from A 

AAA-04a0 
working....from A 

或許我的作用域的理解是錯誤的。如果是這樣,請你解釋一下。

我需要做什麼才能在第二個塊中獲得不同的實例?

+0

'glkernel.BeginLifetimeScope()'調用返回新的作用域對象,但是你沒有使用它,你總是從全局的'glkernel'作用域解析,所以你總是得到相同的實例... – nemesv

回答

2

問題是,你正在解決容器的事情 - glkernel,而不是超出生命週期範圍。一個容器生命週期範圍 - 根生命週期範圍。

解析出生命週期範圍。這可能意味着您需要更改控制器以傳遞組件列表,而不是使用服務位置。

public class Controller 
{ 
    private IEnumerable<IInterface> _interfaces; 
    public Controller(IEnumerable<IInterface> interfaces) 
    { 
    this._interfaces = interfaces; 
    ("controller ins").Dump(); 
    } 

    public void GetA() 
    { 
    foreach(IInterface a in this._interfaces) 
    { 
     a.DoWork("from A"); 
    } 
    } 
} 

然後很容易切換您的解決方案代碼。

using (var scope1 = glkernel.BeginLifetimeScope()){ 
    Controller c1 = scope1.Resolve<Controller>(); 
    c1.GetA(); 
    c1.GetA(); 
} 

using (var scope2 = glkernel.BeginLifetimeScope()){ 
    Controller c2 = scope2.Resolve<Controller>(); 
    c2.GetA(); 
    c2.GetA(); 
} 

該Autofac wiki有一些good information on lifetime scopes you might want to check out

+0

你是對的, @nemesv也是。我重寫了代碼並使其工作。只要指出windsor castle語法就是:使用(kernel.BeginScope()){// code}。 – vikramka