是否可以在 ASP.NET MVC FilterAttribute 上使用依赖注入/IoC?
题
我有一个简单的习惯 FilterAttribute
我用它来装饰各种 ActionMethods
.
例如。
[AcceptVerbs(HttpVerbs.Get)]
[MyCustomFilter]
public ActionResult Bar(...)
{ ... }
现在,我希望向此 CustomFilter Action 添加一些日志记录..所以作为一个好男孩,我正在使用 DI/IoC
...因此希望将这种模式用于我的定制 FilterAttribute
.
所以如果我有以下...
ILoggingService
并希望添加这个我的自定义 FilterAttribute
..我不知道怎么办。就像,我很容易做到以下几点......
public class MyCustomFilterAttribute : FilterAttribute
{
public MyCustomFilterAttribute(ILoggingService loggingService)
{ ... }
}
但是编译器错误地说装饰我的属性 ActionMethod
(以上所列...) 需要 1 个参数 ..所以我只是不知道该怎么做:(
解决方案
我有财产注入工作 忍者 和 Ninject.Web.MVC.
只要您从 Ninject.Web.MVC 获得了控制器工厂,就相当简单了。
例如。
public class EventExistsAttribute : FilterAttribute, IActionFilter
{
[Inject]
public IEventRepository EventRepo { private get; set; }
public void OnActionExecuting(ActionExecutingContext filterContext)
{
//Do stuff
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
//Do something else if you so wish...
}
}
它的缺点是本质上具有“隐藏”依赖性,可以说......但对此你无能为力。
HTH,
查尔斯
其他提示
您需要编写自己的IActionInvoker,做财产注射。看一看的此发布者麦博加德的想法。
是的,可以在 FilterAttribute 上使用依赖注入。但是,不可能在 FilterAttribute 上使用构造函数注入。这不是 ASP.NET MVC 的限制,它是所有 .Net 代码的共同点,如下所示 传递给属性构造函数的值仅限于简单类型.
[MyFilter(ILogger logger)] // this will not compile
public ActionResult Index()
{
return View();
}
所以常见的做法是使依赖成为 财产 您的过滤器,如 @Charlino 的示例所示。然后您可以使用属性注入。您可以使用 Ninject 来装饰过滤器属性,如 @Charlino 的示例所示。或者按照 @mrydengren 的建议,您可以在 ControllerActionInvoker 的自定义子类中执行此操作。