I am trying to find a way to use Ninject to inject constructor dependencies into filters. I am finding many articles describing property injection which is now advised against,
There is a way to use constructor injection.
First you replace your attribute with an 'empty' one which you will just use as a marker
public class UserValidationAttribute : Attribute { }
Then you create a filter class as an IActionFilter
.
public class UserValidationFilter : IActionFilter
{
private readonly IRepository repository;
public UserValidationFilter(IRepository repository)
{
this.repository = repository;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
//do something
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
//do something
}
}
Then you can register it with something like
private static void RegisterServices(IKernel kernel)
{
kernel.BindFilter<UserValidationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<UserValidationAttribute>();
}
If your attribute itself has constructor parameters, you can pass them in like
kernel.BindFilter<UserValidationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<UserValidationAttribute>();
.WithConstructorArgumentFromActionAttribute<UserValidationAttribute>("myParameter", attr => attr.MyParameter);
The BindFilter
syntax is part of Ninject.Web.Mvc.FilterBindingSyntax.
Assuming that the attribute is to be a part of the metadata, which means that it should be instantiated at the compile time, it is not possible to have a repository injected into an attribute by any ioc container. Containers operate in run time.
If you want to inject dependencies to a filer, you want to use property injection instead of constructor injection.
public class UserValidationAttribute : ActionFilterAttribute
{
[Inject]
private IRepository repository { get; set; }
public UserValidationAttribute()
{
}
}
https://stackoverflow.com/a/7192754/296861