Question

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 :(

Was it helpful?

Solution

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

OTHER TIPS

You need to write your own IActionInvoker and do property injection. Have a look at this post by Jimmy Bogard for ideas.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top