Autofac – Registrare più tipi sulla stessa interfaccia

novembre 12, 2017
by Andrea Tosato

Nelle ultime settimane ho iniziato ad utilizzare Autofac. Una delle prime esigenze che ho avuto è stata quella di registrare per la stessa interfaccia più tipi.

Risoluzione dell’interfaccia

Ad  esempio per l’interfaccia INotifyPeopleChanges devo registrare sia il tipo SmsNotifyPeopleChanges che il tipo MailNotifyPeopleChanges. In questo particolare caso, Autofac non riesce a restituire entrambe le istanze registrate. Creo un metodo di estensione che soddisfa la mia problematica.

public static IEnumerable<T> GetAll<T>(this ILifetimeScope lifetimeScope)
  where T: class
{
  IEnumerable<Type> types = lifetimeScope.ComponentRegistry.Registrations
     .Where(r => typeof(T).IsAssignableFrom(r.Activator.LimitType))
     .Select(r => r.Activator.LimitType);
  if(types.Count() <= 1)
    return types.Select(t => lifetimeScope.Resolve(t) as T).ToList();

  return types.Select(t => lifetimeScope.ResolveNamed(t.FullName, t) as T).ToList();
}

Creo un metodo di estensione sull’interfaccia ILifetimeScope di Autofac, il quale, mi consente di risolvere i tipi durante l’esecuzione della mia applicazione.
Nell’oggetto lifetimeScope verifico tutti gli oggetti registrati sul tipo <T> ricercato e per ognuno di essi chiedo al motore di Autofac di risolvere il tipo.
Nel caso in cui ci fossero effettivamente più istanze, oltre al tipo, vado a verificare il nome configurato durante la registrazione.

Registrazione del tipo

Durante la registrazione dei tipi sulle relative interfacce, devo utilizzare anche il metodo Named che mi aiuta a recuperare, come visto in precedenza, la corretta implementazione.

builder.RegisterType<SmsNotifyPeopleChanges>().As<INotifyPeopleChanges>()
     .Named(typeof(SmsNotifyPeopleChanges).FullName, typeof(SmsNotifyPeopleChanges));
builder.RegisterType<MailNotifyPeopleChanges>().As<INotifyPeopleChanges>()
     .Named(typeof(MailNotifyPeopleChanges).FullName, typeof(MailNotifyPeopleChanges));

Applicazione

L’utilizzo del metodo quindi sarà, molto banalmente, come segue:

lifetimeScope.GetAll<INotifyPeopleChanges>();

Una volta recuperata la lista di istanze registrate, potremmo utilizzare le logiche applicative che più ci fanno comodo.

About

Senior Software Developer . NET