2011-02-10 3 views
2

는 등록 된 모든 서비스를받을하기 위해 다음을 수행 할 수 있습니다이름이나 키로 등록되어 있어도 Autofac에서 유형에 대한 모든 서비스를 확인할 수 있습니까? Autofac 하나에서

IEnumerable<MyClass> all = Context.Resolve<IEnumerable<MyClass>>() 

그러나 이것은라는 이름의 서비스로 등록 된 사람들을 포함하지 않습니다.

Autofac 소스를 보면 서비스가 TypedService 또는 KeyedService를 기반으로하는 확인을 위해 쿼리되기 때문인 것으로 보입니다.

이름이 등록되었는지 여부에 관계없이 모든 서비스를 IEnumerable로 확인하는 방법이 있습니까?

답변

5

:

builder.Register<CupOfT>() 
    .As<IBeverage>() 
    .Keyed<IBeverage>("someKey"); 

그런 다음 당신이 뒤에있는 결과를 얻을 수 IEnumerable<IBeverage>를 해결 할 수 있습니다, 키 (또는 이름)로 해결하는 것도 지원됩니다.

IBeverage에 대한 특정 기본 등록을 유지하는 데 우려되는 경우 다른 사람에게 PreseveExistingDefaults()을 사용하거나 (의도 한 기본값이 마지막에 등록되어 있는지 확인하십시오).

HTH!

다음과 같이 당신이 As<T>() 방법과 Named<T>() 방법을 결합 할 수 있음을 나타납니다
+0

빠른 응답에 이어 OP에서 지연된 응답은 매우 선전하지 않습니다. 거대한 사과! 내 질문에 반드시 모든 등록을 통제 할 필요는 없다고 언급 했어야했다. 이것은 사이트를 구축하는 데 사용되는 프레임 워크 (Umbraco 5)에서 Autofac 위에있는 추상화의 일부입니다. 우리 프레임 워크는 다른 컨테이너 나 다른 Autoofac에 대한 비즈니스 또는 다른 의존성을 가진 타사 솔루션에서 사용할 수 있습니다. 공급자 고유의 내부 등록 코드 –

1

작동하는 것으로 보이는 방법을 작성했습니다. Autofac에서이 작업을 수행 할 수있는 방법이 있다면 의견을 보내 주시면 감사하겠습니다. 아래 예제에서 _context 필드는 IComponentContext 유형입니다.

여기에 가장 좋은 옵션은 키와 정기적으로 '입력'서비스를 모두 사용하여 항목을 등록하는 것입니다
public IEnumerable<T> ResolveAll<T>() 
    { 
     // We're going to find each service which was registered 
     // with a key, and for those which match the type T we'll store the key 
     // and later supplement the default output with individual resolve calls to those 
     // keyed services 
     var allKeys = new List<object>(); 
     foreach (var componentRegistration in _context.ComponentRegistry.Registrations) 
     { 
      // Get the services which match the KeyedService type 
      var typedServices = componentRegistration.Services.Where(x => x is KeyedService).Cast<KeyedService>(); 
      // Add the key to our list so long as the registration is for the correct type T 
      allKeys.AddRange(typedServices.Where(y => y.ServiceType == typeof (T)).Select(x => x.ServiceKey)); 
     } 

     // Get the default resolution output which resolves all un-keyed services 
     var allUnKeyedServices = new List<T>(_context.Resolve<IEnumerable<T>>()); 
     // Add the ones which were registered with a key 
     allUnKeyedServices.AddRange(allKeys.Select(key => _context.ResolveKeyed<T>(key))); 

     // Return the total resultset 
     return allUnKeyedServices; 
    } 
+1

을 오히려 여기에'해결()'와'ResolveKeyed을()'를 사용하는 대신, 'ResolveComponent()'메소드의 사용을 고려할 수 있습니다. 동일한 서비스 (또는 동일한 키)에 대해 여러 구현이 존재하는 경우를 더 잘 처리 할 수 ​​있습니다. –

0

:

[TestMethod] 
    public void ResolveTests() 
    { 
     var builder = new ContainerBuilder(); 
     builder.RegisterType<ClassA1>().As<IClassA>().Named<IClassA>("1"); 
     builder.RegisterType<ClassA2>().As<IClassA>().Named<IClassA>("2"); 
     builder.RegisterType<ClassA3>().As<IClassA>().Named<IClassA>("3"); 
     var container = builder.Build(); 

     var allInstances = container.Resolve<IEnumerable<IClassA>>(); 
     allInstances.Count().Should().Be(3); 

     container.ResolveNamed<IClassA>("1").Should().BeAssignableTo<ClassA1>(); 
     container.ResolveNamed<IClassA>("2").Should().BeAssignableTo<ClassA2>(); 
     container.ResolveNamed<IClassA>("3").Should().BeAssignableTo<ClassA3>(); 
    } 
관련 문제