2009-02-16 11 views
17

Después de haber visto cómo NInject can do it y AutoFac can do it Estoy tratando de encontrar la manera de inyectar dependencias en ActionFilters MVC usando el castillo de Windsor¿Cómo uso Windsor para inyectar dependencias en ActionFilterAttributes

En este momento estoy usando una estática fea COI clase de ayuda para resolver las dependencias del código de constructor de la siguiente manera:

public class MyFilterAttribute : ActionFilterAttribute 
{  
    private readonly IUserRepository _userRepository; 
    public MyFilterAttribute() : this(IoC.Resolve<IUserRepository>()) { } 
    public MyFilterAttribute(IUserRepository userRepository) 
    { 
    _userRepository = userRepository; 
    } 
} 

me encantaría para eliminar esa cosa COI antipatrón estática de mis filtros.

Alguna pista a como cómo iba a ir haciendo eso con el castillo de Windsor?

Y no, cambiar el marco DI no es una opción.

Respuesta

10

Hacer un atributo genérico: MyFilterAttribute con Héctor teniendo un tipo como argumento - es decir algo como esto:

public class MyFilterAttribute : ActionFilterAttribute { 
    public MyFilterAttribute(Type serviceType) { 
     this.serviceType = serviceType; 
    } 

    public override void OnActionExecuting(FilterExecutingContext c) { 
     Container.Resolve<IFilterService>(serviceType).OnActionExecuting(c); 
     // alternatively swap c with some context defined by you 
    } 

    // (...) action executed implemented analogously 

    public Type ServiceType { get { return serviceType; } } 
    public IWindsorContainer Container { set; get; } 
} 

continuación, utilizar el mismo enfoque que los dos artículos que usted se refiere, con el fin de tomar el control de cómo se invocan las acciones, y realice una inyección manual de su WindsorContainer en el atributo.

Uso: [myFilter (typeof (IMyFilterService))]

Su filtro real estará entonces en una clase que implementa IMyFilterService que a su vez debe aplicar IFilterService que podría ser algo como esto:

public interface IFilterService { 
    void ActionExecuting(ActionExecutingContext c); 
    void ActionExecuted(ActionExecutedContext c); 
} 

De esta manera, su filtro ni siquiera estará vinculado a ASP.NET MVC, y su atributo no es más que una pieza de metadatos, ¡como se supone que debería ser! :-)

+2

Acepto: los atributos no deben ser "ejecutables" sino solo una etiqueta. –

+2

muchas gracias por su respuesta! Me puse a correr con algunas modificaciones: 1) la línea Container.Resolve requiere un parámetro genérico. Lo cambié para usar Container.Resolve (serviceType) y lo fundí. 2) Heredé mvccontrib WindsorControllerFactory y agregué ActionInvoker en CreateController(). –

18

Cuando necesitaba esto, lo basó en el trabajo que otros han hecho con Ninject y Windsor para conseguir property injection dependencies on my ActionFilters.

+3

Preferí el método en ese enlace también. –

+0

¡Buen post gracias! Lo estoy trabajando muy rápido y el uso es mucho mejor que la opción genérica MyFilterAttribute –

Cuestiones relacionadas