2011-11-15 12 views
5

Estoy tratando de aplicar la función de autor de decodificador autofac a mi escenario sin éxito. Parece que en mi caso no asigna correctamente el nombre a los registros.Autofac decorar genéricos abiertos registrados utilizando escaneado de ensamblaje

¿Hay alguna manera de registrar tipos de ensamblados escaneados con un nombre, para poder usarlo luego en la clave decorativa genérica abierta?

¿O tal vez estoy completamente equivocado y estoy haciendo algo inapropiado aquí?

builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly) 
    .AsClosedTypesOf(typeof(IAggregateViewRepository<>)) //here I need name, probably 
    .Named("view-implementor", typeof(IAggregateViewRepository<>)) 
    .SingleInstance(); 

builder.RegisterGenericDecorator(typeof(CachedAggregateViewRepository<>), 
    typeof(IAggregateViewRepository<>), fromKey: "view-implementor"); 

Respuesta

13

Aquí hay un intento, no delante de Visual Studio para la resolución de sobrecarga podría no ser exactamente correcto:

builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly) 
    .As(t => t.GetInterfaces() 
       .Where(i => i.IsClosedTypeOf(typeof(IAggregateViewRepository<>)) 
       .Select(i => new KeyedService("view-implementor", i)) 
       .Cast<Service>()) 
    .SingleInstance(); 
  • Named() es el azúcar solo sintáctica para Keyed(), que asocia el componente con un KeyedService
  • As() acepta Func<Type, IEnumerable<Service>>

También necesitará:

using Autofac; 
using Autofac.Core; 
+0

funciona como un encanto! ¡Muchas gracias! – achekh

+0

¡Genial! Alegra oírlo. –

+1

Esto funcionó para mí también. No obstante, no creo que se necesite el Cast (). – luksan

2

Si quería limpiar su código de registro también se puede definir el siguiente método de extensión adicional (muy detallado y basado en la fuente autofac para el otro sobrecarga, pero sólo debe definirse una vez):

using Autofac; 
using Autofac.Builder; 
using Autofac.Core; 
using Autofac.Features.Scanning; 

public static class AutoFacExtensions 
{ 
    public static IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle> 
     AsClosedTypesOf<TLimit, TScanningActivatorData, TRegistrationStyle>(
      this IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle> registration, 
      Type openGenericServiceType, 
      object key) 
     where TScanningActivatorData : ScanningActivatorData 
    { 
     if (openGenericServiceType == null) throw new ArgumentNullException("openGenericServiceType"); 

     return registration.As(t => 
      new[] { t } 
      .Concat(t.GetInterfaces()) 
      .Where(i => i.IsClosedTypeOf(openGenericServiceType)) 
      .Select(i => new KeyedService(key, i))); 
    } 
} 

Eso le permitiría simplemente hacer esto:

builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly) 
    .AsClosedTypesOf(typeof(IAggregateViewRepository<>), "view-implementor") 
    .SingleInstance(); 
Cuestiones relacionadas