Autofac: résout toutes les instances d'un Type

Compte tenu des enregistrements suivants

builder.Register<A>().As<I>();
builder.Register<B>().As<I>();
builder.Register<C>().As<I>();

var container = builder.Build();

Je cherche à résoudre toutes les instances de type I en tant que IEnumerable (Tableau ou Collection peu importe).

À Windsor, j'aurais écrit ce qui suit.

foreach(I i in container.ResolveAll<I>())
{
 ...
}

Je migre de Windsor vers Autofac 1.4.4.561 mais je ne peux pas voir la syntaxe équivalente.

53
demandé sur Keith Pinson 2009-09-10 19:57:20

2 réponses

Pour les versons actuels D'Autofac: (2.0+, donc tout ce que vous devriez utiliser aujourd'hui)

Vous enregistrez plusieurs ILoggers (par exemple):

var builder = new ContainerBuilder();

builder.Register<ConsoleLogger>()
  .As<ILogger>();

builder.Register<EmailLogger>()
  .As<ILogger>()
  .PreserveExistingDefaults(); //keeps console logger as the default

Ensuite, obtenez tous les ILoggers:

var loggers = container.Resolve<IEnumerable<ILogger>>();

Vous n'avez pas besoin de faire quelque chose de spécial, demandez simplement un IEnumerable<T> du type désiré. Autofac a un support de collection prêt à l'emploi, ainsi que d'autres adaptateurs qui peuvent envelopper vos composants avec des fonctionnalités supplémentaires.

C'est le même usage que le pré-2.x ImplicitCollectionSupportModule, mais cuit à droite.

Pour les anciennes versions (0.X - 1.4)

Deux façons:

1) Utilisez l'enregistrement de collection

var builder = new ContainerBuilder();
builder.RegisterCollection<ILogger>()
  .As<IEnumerable<ILogger>>();

builder.Register<ConsoleLogger>()
  .As<ILogger>()
  .MemberOf<IEnumerable<ILogger>>();

builder.Register<EmailLogger>()
  .As<ILogger>()
  .MemberOf<IEnumerable<ILogger>>();

Puis:

var loggers = container.Resolve<IEnumerable<ILogger>>();

Ce qui vous donne un IEnumerable.

Ou 2) Vous pouvez utiliser le module ImplicitCollectionSupport, qui fera fonctionner le code comme les nouvelles versions D'Autofac:

builder.RegisterModule(new ImplicitCollectionSupportModule());
builder.Register(component1).As<ILogger>;
builder.Register(component2).As<ILogger>;

Ensuite, résolvez une collection de ILogger plutôt que de chercher à résoudre tout.

var loggers = container.Resolve<IEnumerable<ILogger>>();

Ce qui vous donne un IEnumerable, encore une fois.

75
répondu Philip Rieck 2018-07-03 14:50:59

Une mise à jour pour le bien de la nouvelle (2.x) version. Tout ce dont vous avez besoin maintenant est:

container.Resolve<IEnumerable<I>>();

Il n'y a plus besoin de RegisterCollection() ou ImplicitCollectionSupportModule - cette fonctionnalité sort de la boîte.

54
répondu Nicholas Blumhardt 2010-08-26 11:55:37