2013-01-23 2 views
7

두 스코프가 있는데 하나는 다른 안에 중첩되어 있습니다. 특정 서비스를 해결할 때 하나의 구성 요소를 하나의 루트 범위에서 확인하고 다른 구성 요소를 하위 범위에서 확인하고 싶습니다. 이 작업을 수행하는 쉬운 방법이 있습니까?Autofac을 사용하여 다른 범위의 다른 구성 요소를 반환

나는 현재 범위가 무엇인지를 결정하는 팩토리 클래스를 사용하여 작업 한 다음 해당 인스턴스를 돌려 무언가를 얻는 것을 처리했다 :

이 방법에 문제가 있습니다
IContainer BuildContainer() 
{ 
    var builder = new ContainerBuilder(); 

    // ... 
    builder.RegisterType<FooInParentScope>().AsSelf(); 
    builder.RegisterType<FooInChildScope>().AsSelf(); 
    builder.RegisterType<FooFactory>().AsImplementedInterfaces(); 
    builder.Register<IFoo>(c => c.Resolve<IFooFactory>().GetFoo()).InstancePerLifetimeScope(); 
    // ... 
} 


class FooFactory : IFooFactory 
{ 
    private readonly ILifetimeScope m_scope; 

    public FooFactory(ILifetimeScope scope) 
    { 
     m_scope = scope; 
    } 

    public IFoo GetFoo() 
    { 
     if (m_scope.Tag == "ParentScope") 
      return m_scope.Resolve<FooInParentScope>(); 
     else 
      return m_scope.Resolve<FooInChildScope>(); 
    } 
} 

class FooInParentScope : IFoo 
{ 
} 

class FooInChildScope : IFoo 
{ 
} 

:

  1. IFooFactory가 실제로 필요한 경우 여분의 클래스 (또는 2 - 확실하지 않음)를 추가해야합니다.
  2. 위 코드는 ParentScope에 중첩 된 다른 범위를 처리하지 않습니다. 범위를 Autofac.Core.Lifetime.LifetimeScope으로 캐스팅하고 ParentLifetimeScope 속성을 검사하여이 문제를 해결할 수 있지만 특히 안전하지는 않습니다.

답변

10

루트 컨테이너에 FooInParentScope를 SingleInstance로 등록 할 수 있습니다. inner lifetimescope를 만들 때 FooInChildScope에 대한 등록을 SingleInstance (등록 무시)로 추가하십시오.

builder.RegisterType<FooInParentScope>().As<IFoo>.SingleInstance(); 
var container = builder.Build(); 

var childScope = container.BeginLifetimeScope(innerBuilder => 
    { 
     // override registration for IFoo in child lifetime scope: 
     innerBuilder.RegisterType<FooInChildScope>().As<IFoo>().SingleInstance(); 
    }); 

FooInParentScope fooInParentScope = (FooInParentScope) container.Resolve<IFoo>(); 
FooInChildScope fooInChildScope = (FooInChildScope) childScope.Resolve<IFoo>(); 
+2

그건 내가 생각하지 못한 방식입니다. 단점은 범위를 작성하는 시점에 한 곳에서 모든 것을 가지지 않고 추가 등록을해야한다는 것입니다. –

관련 문제