2014-06-23 12 views
9

Si consideri il seguenteOttenere un elenco di tutti gli oggetti registrati di attuazione di una certa interfaccia

builder.Register(c => new A()); 
builder.Register(c => new B()); 
builder.Register(c => new C()); 

B e C sono entrambi ISomeInterface.

Vorrei ora ottenere uno IEnumerable di tutti gli oggetti registrati che implementano ISomeInterface.

Come posso realizzare questo in Autofac?

+0

Autofac non lo fa supportare davvero quello che stai chiedendo. Se non puoi modificare le registrazioni, potresti essere protetto. Eventuali domande contro la raccolta di registrazioni non tengono necessariamente conto delle fonti di registrazione dinamica (alcune delle quali sono registrate automaticamente nel contenitore) per supportare cose come "IEnumerable "). Quello che ottieni dalla query potrebbe non essere un elenco completo. –

risposta

12

appena provato questo, funziona e non dipende dal contesto di vita:

tipi enumerazione utilizzando Activator invece

var types = con.ComponentRegistry.Registrations.Where(r => typeof(ISomeInterface).IsAssignableFrom(r.Activator.LimitType)).Select(r => r.Activator.LimitType); 

Poi, per risolvere:

IEnumerable<ISomeInterface> lst = types.Select(t => con.Resolve(t) as ISomeInterface); 
+0

Bello. Più pulito della mia implementazione. – kasperhj

19

Se hai

container.Register(c => new A()).As<ISomeInterface>(); 
container.Register(c => new B()).As<ISomeInterface>(); 

Poi, quando si fa

var classes = container.Resolve<IEnumerable<ISomeInterface>>(); 

Si otterrà una variabile che è una lista di ISomeInterface, contenente A e B

+0

Questo non funziona. I componenti non sono registrati come 'ISomeInterface', ma li implementano comunque. – kasperhj

+0

Non puoi fare: container.Register (c => new SomeClassA()). Come ()? –

+0

Purtroppo no, no. La registrazione effettiva non è sotto il mio controllo. – kasperhj

2

Ecco come ho fatto io esso.

var l = Container.ComponentRegistry.Registrations 
      .SelectMany(x => x.Services) 
      .OfType<IServiceWithType>() 
      .Where(x => 
       x.ServiceType.GetInterface(typeof(ISomeInterface).Name) != null) 
      .Select(c => (ISomeInterface) c.ServiceType); 
+0

Questo non funziona per me: non riesce nella clausola 'Select' con' System.InvalidCastException: 'Impossibile lanciare l'oggetto di tipo' System.RuntimeType 'per digitare' MyCompany.Communications. Core.ICommunicationService '' '. – Tagc