2011-03-21 23 views
13

que tiene la siguiente inscripciónautofac en la liberación v2.4.5.724

builder.Register<Func<Type, IRequestHandler>>(
      c => request => (IRequestHandler)c.Resolve(request)); 

Básicamente estoy tratando de registrar un método de fábrica que resuelve un caso de IRequestHandler de un tipo dado.

Esto funciona bien hasta la versión 2.4.3.700. Pero ahora estoy obteniendo el siguiente error ...

No se puede acceder a un objeto eliminado. Nombre del objeto: 'Esta operación de resolución ya ha finalizado. Cuando registra componentes usando lambdas, el parámetro IComponentContext 'c' a no se puede almacenar la lambda. En su lugar, resuelve IComponentContext nuevamente de 'c', o resuelve un Func > basado en de fábrica para crear los componentes posteriores de. '.

ACTUALIZACIÓN

yo estaba tratando de limitar la exposición de autofac con el resto de los proyectos de la solución. Nick, gracias por la pista, ahora mi registro se parece a esto ...

builder.Register<Func<Type,IRequestHandler>>(c => 
     { 
      var handlers = c.Resolve<IIndex<Type,RequestHandler>>(); 
      return request => handlers[request]; 
     }); 

Respuesta

20

El c en esta expresión es temporal, por lo que este código mientras que anteriormente funcional, está roto. Autofac 2.4.5 detecta este problema mientras versiones anteriores lo ignoran silenciosamente.

Para solucionar el problema, explícitamente resolver IComponentContext:

builder.Register<Func<Type, IRequestHandler>>(c => { 
    var ctx = c.Resolve<IComponentContext>(); 
    return request => (IRequestHandler)ctx.Resolve(request)); 
}); 

La funcionalidad que está emulando aquí podría estar mejor representada mediante las teclas y los índices, por ejemplo ver Interrupted chain of IoC o http://code.google.com/p/autofac/wiki/TypedNamedAndKeyedServices.

0

Tuve un problema similar al del usuario6130. Quería evitar el uso de IIndex en la implementación de mi clase y, en su lugar, pasar una resolución de servicio a mi constructor.

así que ahora tengo mi aplicación de servicio con el siguiente constructor:

public MvcMailer(Converter<string, MailerBase> mailerResolver) 
{ 
    _resolver = mailerResolver; 
} 

quería utilizado los servicios con clave sin tener que depender directamente en el espacio de nombres Autofac. Estaba obteniendo el mismo error hasta que reestructuré la configuración como tal.

1) buscará todos mis implementaciones del anuncio publicitario y el índice a través de nombre de la clase (podría mejorarse)

builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()) 
     .Where(t => t.Name.EndsWith("Mailer")).Keyed<Mvc.Mailer.MailerBase>(t => t.Name.Replace("Mailer", "").ToLower()); 

2) registrar el convertidor en Autofac config

builder.Register<System.Converter<string,Mvc.Mailer.MailerBase>>(c => { 
    var all = c.Resolve<Autofac.Features.Indexed.IIndex<string,Mvc.Mailer.MailerBase>>(); 
     return delegate(string key) 
     { 
       return all[key]; 
     }; 
    }); 

3) Regístrese como otros tipos de componentes y deje que Autofac maneje la inyección del convertidor

builder.RegisterType<Mailers.MvcMailer>().As<Mailers.IMailer>(); 

Cuestiones relacionadas