Reputation: 86967
I've got a simple custom FilterAttribute
which I use decorate various ActionMethods
.
eg.
[AcceptVerbs(HttpVerbs.Get)]
[MyCustomFilter]
public ActionResult Bar(...)
{ ... }
Now, I wish to add some logging to this CustomFilter Action .. so being a good boy, I'm using DI/IoC
... and as such wish to use this pattern for my custom FilterAttribute
.
So if i have the following...
ILoggingService
and wish to add this my custom FilterAttribute
.. i'm not sure how. Like, it's easy for me to do the following...
public class MyCustomFilterAttribute : FilterAttribute
{
public MyCustomFilterAttribute(ILoggingService loggingService)
{ ... }
}
But the compiler errors saying the attribute which decorates my ActionMethod
(listed above...) requires 1 arg .. so i'm just not sure what to do :(
Upvotes: 2
Views: 602
Reputation: 6086
Yes it is possible to use dependency injection on a FilterAttribute. However it not possible to use constructor injection on a FilterAttribute. This is not a limitation of ASP.NET MVC, it is a common to all .Net code, as the values passed into an attributes constuctor are limited to simple types.
[MyFilter(ILogger logger)] // this will not compile
public ActionResult Index()
{
return View();
}
So the common practice is to make the dependency a property of your filter, as in @Charlino's example. You can then use property injection. You can use Ninject to decorate the filter property as in @Charlino's example. Or as suggested by @mrydengren, you can do this in a custom subclass of ControllerActionInvoker.
Upvotes: 2
Reputation: 15890
I've got property injection working with Ninject and the Ninject.Web.MVC.
As long as you've got the controller factory from Ninject.Web.MVC, it's rather simple.
E.g.
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...
}
}
It has the drawback of essentially having a 'hidden' dependency, so to say... but there ain't much you can do about that.
HTHs,
Charles
Upvotes: 3
Reputation: 4260
You need to write your own IActionInvoker and do property injection. Have a look at this post by Jimmy Bogard for ideas.
Upvotes: 2