2013-10-01 14 views
1

Autofac의 유효 범위를 평가하려고합니다. 인스턴스를 InstancePerLifetimeScope로 선언 한 다음 using (container.BeginLifetimeScope()) 블록에서 인스턴스를 가져와야합니다. 같은 인스턴스. 그러나 다른 블록에서는 다른 인스턴스를 얻어야합니다. 하지만 내 코드 (linqpad에서) 내게 같은 인스턴스를 제공합니다. 그러나 윈저의 생활관은 내가 생각한대로 작동합니다.BeginLifetimeScope가 작동하지 않는 Autofac LifetimeScope

코드 :

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 위키는 일부 good information on lifetime scopes you might want to check out있다.

+0

당신은 맞습니다. @nemesv 역시 위와 같습니다. 코드를 다시 작성하고 작동 시켰습니다. 똑같은 윈저 성 구문은 using (kernel.BeginScope()) {// code}입니다. – vikramka