2011-01-23 21 views
6

Por ejemplo, he registrado la clase C1 con un parámetro en el constructor de tipo System.Type. Tengo otra clase (C2) con parámetro inyectado de tipo C1. Y quiero recibir typeof(C2) automáticamente en C1 constructor. ¿Es posible de alguna manera?¿Es posible obtener el tipo de contenedor en AutoFac

código Ejemplo:

public class C1 
{ 
    public C1(Type type) {} 

    // ... 
} 

public class C2 
{ 
    public C2(C1 c1) {} 

    // ... 
} 

// Registration 
containerBuilder.Register(???); 
containerBuilder.Register<C2>(); 

Respuesta

7

Esto debe hacerlo:

builder.RegisterType<C1>(); 
builder.RegisterType<C2>(); 
builder.RegisterModule(new ExposeRequestorTypeModule()); 

Dónde:

class ExposeRequestorTypeModule : Autofac.Module 
{ 
    Parameter _exposeRequestorTypeParameter = new ResolvedParameter(
     (pi, c) => c.IsRegistered(pi.ParameterType), 
     (pi, c) => c.Resolve(
      pi.ParameterType, 
      TypedParameter.From(pi.Member.DeclaringType))); 

    protected override void AttachToComponentRegistration(
      IComponentRegistry registry, 
      IComponentRegistration registration) 
    { 
     registration.Preparing += (s, e) => { 
      e.Parameters = new[] { _exposeRequestorTypeParameter } 
       .Concat(e.Parameters); 
     }; 
    } 
} 

Cualquier componente que toma un parámetro System.Type va a obtener el tipo de solicitante pasado (si hay alguno). Una posible mejora podría ser usar un NamedParameter en lugar de que TypedParameter para restringir los parámetros Type que se emparejarán solo con aquellos con un nombre determinado.

Háganme saber si esto funciona, otros han preguntado acerca de la misma tarea general y sería bueno compartirla con ellos.

+0

No, desafortunadamente, no funciona. LimitType es el tipo de componente en sí (C1 en este caso) – oryol

+0

Ah - doh! - gracias por eso. Voy a pensar en alternativas y publicarlas aquí si encuentro alguna. –

+0

El principal problema está en AutowiringParameter. Siempre invoca resolución para niños sin parámetros (con enumerable vacío). Creé un parámetro similar y lo registré en registration.ActivatorData.ConfiguredParameters (donde ActivatorData es ReflectionActivatorData) con valor: registration.ActivatorData.ImplementationType. Pero funciona solo para c.Resolve explícita (y con la inyección de C1 mismo obtuve 'No se encontraron constructores ...' para C1) .. – oryol

Cuestiones relacionadas