3

I have this DDD application that has MVC on the Presentation, with Ninject.

I have the CrossCutting Layer binding the injections from all the layers, and it works like a charm.

What i can't make work, is when it comes to Filter Attributes. I have this filter that checks one cookie and depending on it's value, executes queries on the Database. With this Architecture, i just can't make my Filter access my Repository directly, it would be disrespectful to the methodology i'm applying.

I have my IFooAppService interface and have it's methods that eventually will hit the repository for Data requesting. I can successfully inject it in any Controller constructor and it will execute my _fooAppService.Query(), but i have this XooFilter above some actions in my application, and i just can't pass my _fooAppService to it. Here's my XooFilter:

public class XooFilter : ActionFilterAttribute
{
    private readonly IFooAppService _fooAppService;

    public XooFilter(IFooAppService fooAppService)
    {
        _fooAppService = fooAppService;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // LOGIC...

        var fooValue = _fooAppService.Query();

        // MORE LOGIC..
    }
}

But, when i insert my filter above any Action [XooFilter], it won't work. It says the filter has no constructor with 0 elements.

I just can't figure it out how to do it nicely and keep the characteristics from DDD and IoC. I found the article below, but couldn't find any answer:

Injecting dependencies into ASP.NET MVC 3 action filters. What's wrong with this approach?

Community
  • 1
  • 1
Edgar Froes
  • 768
  • 8
  • 20
  • [Don't inject dependency into your attributes](https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=98). Period! Make your [attributes passive](http://blog.ploeh.dk/2014/06/13/passive-attributes/), or make your attribute a [humble object](http://xunitpatterns.com/Humble%20Object.html) as described [here](https://stackoverflow.com/questions/29915192/unity-property-injection-on-authorizeattribute/29916075#29916075). – Steven May 05 '15 at 18:34
  • What should i do then? I need to access the database every time these filters are called. EDIT: I'm pretty new to IoC and DI buddy, but i got the basics. – Edgar Froes May 05 '15 at 19:11
  • After you've read the referenced articles and answer, you'll have enough information to make an informed decision about how to solve your problem. – Steven May 05 '15 at 19:19

2 Answers2

0

You could resolve your service this way

System.Web.Mvc.DependencyResolver.Current.GetService(typeof (IFooAppService ));
Nicolas Boisvert
  • 1,141
  • 2
  • 10
  • 26
0

There's a Ninject extension package called Ninject.Web.Mvc (which you may already have). This allows you to set filter binding like so;

public class LoggingModule : NinjectModule
{
    public override void Load()
    {
        this.Bind<ILog>().ToMethod(GetLogger);
        this.BindFilter<LogFilter>(FilterScope.Controller, 0)
            .WithConstructorArgument("logLevel", Level.Info);
    }

    private static ILog GetLogger(IContext ctx)
    {
        var filterContext = ctx.Request.ParentRequest.Parameters
            .OfType<FilterContextParameter>().SingleOrDefault();

        return
            LogManager.GetLogger(filterContext == null
                ? ctx.Request.Target.Member.DeclaringType
                : filterContext.ActionDescriptor.ControllerDescriptor.ControllerType);
    }
}

Note the BindFilter method call. This works as of v.3.3.0.

Once configured, using it is like the usual constructor injection;

public class LogFilter : IActionFilter
{
    public LogFilter(ILog logger)
    {
        // store your instance of "logger" here
    }
}
DiskJunky
  • 4,750
  • 3
  • 37
  • 66