Ninject: 属性 注入 ActionFilterAttribute
Ninject: property injection into ActionFilterAttribute
我想通过 Ninject 在 ActionFilterAttribute 中实现 DI。我找到了 this manual(实际上我今天已经阅读了数十篇),但它是针对 Unity 的。我在 Ninject 上实现它的尝试在这里:
public class MyFilter : ActionFilterAttribute
{
[Inject]
public IDepend Depend { get; set; }
// another code
}
绑定:
public class NinjectResolver : IDependencyResolver
{
// another code
private IKernel AddRequestBindings(IKernel kernel)
{
// another code
kernel.Bind<IDepend>().To<Depend>();
return kernel;
}
}
自定义 FilterProvider:
public class WebApiNinjectActionFilterProvider : ActionDescriptorFilterProvider, IFilterProvider
{
private readonly IKernel _kernel;
private readonly IEnumerable<IFilterProvider> _filterProviders;
public WebApiNinjectActionFilterProvider(IKernel kernel, IEnumerable<IFilterProvider> filterProviders)
{
_kernel = kernel;
_filterProviders = filterProviders;
}
public new IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
{
var filters = _filterProviders.SelectMany(fp => fp.GetFilters(configuration, actionDescriptor)).ToList();
foreach (var filter in filters)
{
// GET ActivationException HERE!!!!!
_kernel.Inject(filter.Instance);
}
return filters;
}
public static void RegisterFilterProviders(IKernel ninjectKernel)
{
var providers = GlobalConfiguration.Configuration.Services.GetFilterProviders().ToList();
GlobalConfiguration.Configuration.Services.Add(typeof(IFilterProvider),
new WebApiNinjectActionFilterProvider(ninjectKernel, providers));
var defaultprovider = providers.First(i => i is ActionDescriptorFilterProvider);
GlobalConfiguration.Configuration.Services.Remove(typeof(IFilterProvider), defaultprovider);
}
}
从 WebApiConfig 调用:
public static void Register(HttpConfiguration config)
{
var ninjectKernel = new StandardKernel();
config.DependencyResolver = new NinjectResolver(ninjectKernel);
WebApiNinjectActionFilterProvider.RegisterFilterProviders(ninjectKernel);
}
最后行动:
[MyFilter]
public async Task<string> Test()
{
return "Hello world";
}
问题是我在这一行中得到一个 ActivationException:
_kernel.Inject(filter.Instance);
ActivationException 的激活路径:
2) 将依赖项 IDepend 注入 属性 依赖类型 MyFilter
1) 请求 MyFilter
如果向控制器注入相同的 属性 - 它注入正常。有什么改进我的代码的想法吗?
我以错误的方式执行 IActionFilter DI。我在 this blogpost of Mark Seemann.
中找到的正确方法
通过 Ninject 的 DI 是这样实现的:
var myFilter = new MyFilter(ninjectKernel.Get<IDepend>());
config.Filters.Add(myFilter);
我想通过 Ninject 在 ActionFilterAttribute 中实现 DI。我找到了 this manual(实际上我今天已经阅读了数十篇),但它是针对 Unity 的。我在 Ninject 上实现它的尝试在这里:
public class MyFilter : ActionFilterAttribute
{
[Inject]
public IDepend Depend { get; set; }
// another code
}
绑定:
public class NinjectResolver : IDependencyResolver
{
// another code
private IKernel AddRequestBindings(IKernel kernel)
{
// another code
kernel.Bind<IDepend>().To<Depend>();
return kernel;
}
}
自定义 FilterProvider:
public class WebApiNinjectActionFilterProvider : ActionDescriptorFilterProvider, IFilterProvider
{
private readonly IKernel _kernel;
private readonly IEnumerable<IFilterProvider> _filterProviders;
public WebApiNinjectActionFilterProvider(IKernel kernel, IEnumerable<IFilterProvider> filterProviders)
{
_kernel = kernel;
_filterProviders = filterProviders;
}
public new IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
{
var filters = _filterProviders.SelectMany(fp => fp.GetFilters(configuration, actionDescriptor)).ToList();
foreach (var filter in filters)
{
// GET ActivationException HERE!!!!!
_kernel.Inject(filter.Instance);
}
return filters;
}
public static void RegisterFilterProviders(IKernel ninjectKernel)
{
var providers = GlobalConfiguration.Configuration.Services.GetFilterProviders().ToList();
GlobalConfiguration.Configuration.Services.Add(typeof(IFilterProvider),
new WebApiNinjectActionFilterProvider(ninjectKernel, providers));
var defaultprovider = providers.First(i => i is ActionDescriptorFilterProvider);
GlobalConfiguration.Configuration.Services.Remove(typeof(IFilterProvider), defaultprovider);
}
}
从 WebApiConfig 调用:
public static void Register(HttpConfiguration config)
{
var ninjectKernel = new StandardKernel();
config.DependencyResolver = new NinjectResolver(ninjectKernel);
WebApiNinjectActionFilterProvider.RegisterFilterProviders(ninjectKernel);
}
最后行动:
[MyFilter]
public async Task<string> Test()
{
return "Hello world";
}
问题是我在这一行中得到一个 ActivationException:
_kernel.Inject(filter.Instance);
ActivationException 的激活路径:
2) 将依赖项 IDepend 注入 属性 依赖类型 MyFilter
1) 请求 MyFilter
如果向控制器注入相同的 属性 - 它注入正常。有什么改进我的代码的想法吗?
我以错误的方式执行 IActionFilter DI。我在 this blogpost of Mark Seemann.
中找到的正确方法通过 Ninject 的 DI 是这样实现的:
var myFilter = new MyFilter(ninjectKernel.Get<IDepend>());
config.Filters.Add(myFilter);