2009-02-16 24 views
17

我们已经看到我是如何NInject can do itAutoFac can do it试图找出如何使用温莎城堡如何使用温莎依赖注入ActionFilterAttributes

目前我使用的是一个丑陋的静态到依赖注入MVC​​ ActionFilters IoC的辅助类来解决从构造函数代码依赖这样的:

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

我很想从我的过滤器去除静态反模式的IoC的事情。

任何暗示,我会如何去做与温莎城堡?

而且,不改变DI框架不是一种选择。

回答

10

做一个通用属性:MyFilterAttribute与男星拍摄类型作为参数 - 即是这样的:

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; } 
} 

然后用同样的方法,你指的是两篇文章,以便采取的控制如何调用动作,以及将WindsorContainer手动注入到属性中。

用法: [MyFilter(typeof运算(IMyFilterService))]

那么你实际的过滤器将在实施IMyFilterService类这反过来应该实现IFilterService这可能是这个样子:

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

这样你的过滤器甚至不会绑定到ASP.NET MVC,而你的属性仅仅是一段元数据 - 它实际上应该是这样的! :-)

+2

我同意:属性不应该是“可执行的”,而只是一个标签。 – 2009-02-16 23:24:53

+2

非常感谢您的回答!我运行了几个mods:1)Container.Resolve行需要一个通用参数。我改变它使用Container.Resolve(serviceType)并将其转换。 2)我继承了mvccontrib WindsorControllerFactory并在CreateController()中添加了ActionInvoker。 – 2009-02-17 08:23:59