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);