2011-02-23 2 views
11

뭔가 :Autofac 컨테이너 빌더에서 기존 등록을 제거 할 수 있습니까? 그 라인을 따라

builder.RegisterType<MyType>().As<IType>(); 
builder.RegisterType<MyType2>().As<IType>(); 
builder.DeRegisterType<MyType>().As<IType>() 

var container = builder.Build(); 
var types = container.Resolve<IEnumerable<IType>>(); 
Assert.IsTrue(types.Count == 1); 
Assert.IsTrue(types[0].GetType == typeof(MyType2)); 

시나리오 : 나는 어셈블리의 무리를 통과하고 내가 가서 내가 유형을 등록하지만 난 원하는 내가 주어진 유형의 하나의 구현이 있는지 확인하십시오. 컨테이너를 만들기 전에이 작업을 수행해야합니다. 나는 그것을 독자적으로 추적 할 수 있었지만 Autofac이 나를 조금 도와 줄 수 있다면 좋을 것입니다.

+0

나는 이것을 원하면 또 다른 이유가있다. RegisterAssemblyTypes를 사용하면 'InstancePerDependencyScope'해상도의 기본 '배경'을 얻는다. 이 후 그들 중 일부를'InstancePerLifetimeScope'으로 업그레이드하려고합니다. 이것은 일부 인터페이스 (예 : 둘 이상의 클래스에서 구현되는 인터페이스)의 열거 형을 해결할 때까지 다시 등록함으로써 정상적으로 작동합니다. '배경'등록을 제거하면이를 허용 할 수 있습니다. –

+2

필자가 특별히 지적한 'RegisterAssemblyTypes(). ()'및 기타 등록 된 어셈블리 유형의 선택 및 처리를 제어 할 수있는 유창한 방법을 발견했습니다. –

답변

11

새 것으로 다시 시작하지 않는 한 ContainerBuilder을 사용하여 직접 수행 할 수 없습니다. 첫 번째 컨테이너를 만들었 으면 원치 않는 유형을 필터링하여 새 컨테이너를 구성하고 첫 번째 컨테이너에서 등록을 다시 사용할 수 있어야합니다. 이와 같이 :

... 
var container = builder.Build(); 

builder = new ContainerBuilder(); 
var components = container.ComponentRegistry.Registrations 
        .Where(cr => cr.Activator.LimitType != typeof(LifetimeScope)) 
        .Where(cr => cr.Activator.LimitType != typeof(MyType)); 
foreach (var c in components) 
{ 
    builder.RegisterComponent(c); 
} 

foreach (var source in c.ComponentRegistry.Sources) 
{ 
    cb.RegisterSource(source); 
} 

container = builder.Build(); 

이것은 매우 우아하지 않지만 작동합니다. 이제 에 대해 자세히 설명 할 수 있다면 왜을 원하십니까? 더 좋은 방법이 있습니다.

+0

이유 부분 추가 ​​ –

+0

현명한 아이디어. 당신은 또한 RegistrationSources 속성을 가로 질러 복사해야 할 것입니다,하지만 이것은 효과가 있습니다. –

+1

@Nicholas - 소스 복사가 추가되었습니다. 또한 그것이 어떤 영향을 미쳤는 지 모르지만, 나는'LifetimeScope' 구성 요소의 중복으로 끝났습니다. 그래서 그것도 필터링. –

1

피터 L.은 아마도 가장 직접적인 옵션을 가지고있을 것입니다.

문제를 완전히 해결하려면 구성 요소를 발견하는 방식을 수정하여 등록 전에 필터링 할 수 있습니까? 이 문제를 해결할 수있는 방법이 있어야만하는 것 같습니다 ... 유지할 구성 요소와 제거 할 구성 요소를 결정하기 위해 트랙을 따라 내려가는 것이 더 어려울 수도 있습니다.

더 많은 방법은 원하지 않는 것을 필터링하기 위해 IEnumerable 지원을 무시하는 것입니다. 나는. 이 코드를 복사하고 수정하여 원하지 않는 구성 요소를 제외하는 FilteredCollectionSource을 작성하십시오.

var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService); 

이 될 것입니다 :

var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService) 
    .Where(reg => /* not a duplicate */); 

당신이 당신의 FilteredCollectionSource가 대신 익숙해해야합니다 RegisterSource()를 사용하여 빌더에 추가하는 경우 내장 된 하나.

+0

불행히도 일괄 처리 된 구성 요소를 얻었으므로 일괄 처리 수는 알 수 없습니다. 도와 주셔서 감사합니다 –

관련 문제