error-handling - WebAPI 自定义 ExceptionFilterAttribute 中的 Ninject 属性注入(inject)不起作用

标签 error-handling asp.net-web-api ninject

我正在尝试使用 Ninject 将 EventLogger 实例注入(inject)自定义 ExceptionFilterAttribute 中。每当我运行代码时,EventLogger 实例为空。我已经实现了一个 IFilterProvider 来以类似的方式为我的自定义 AuthorizationFilterAttribute 解决依赖关系,并且效果很好。有什么想法吗?

不工作

public class ErrorHandlingAttribute : ExceptionFilterAttribute
{
    [Inject]
    public IEventLogger EventLogger { get; set; }

    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
       EventLogger.LogException(actionExecutedContext.Exception);

        actionExecutedContext.Response = actionExecutedContext.Request.
            CreateResponse(HttpStatusCode.BadRequest, 
            new ServiceErrorResponseDTO("An unhandled exception occurred while calling " + 
                actionExecutedContext.Request.RequestUri.ToString() + 
                ". This event has been logged. If you continue to receive this error contact Weichert"));
    }
}

工作

public class RequireAuthorizationAttribute : AuthorizationFilterAttribute
{
    [Inject]
    public IServiceRepository ServiceRepository { get; set; }

    public override void OnAuthorization(HttpActionContext actionContext)
    {


        #region Header Authentication

        var authHeader = actionContext.Request.Headers.Authorization;
        if (authHeader != null)
        {

自定义 IFilterProvider

public class NinjectWebApiFilterProvider : IFilterProvider
{
    private IKernel _kernel;

    public NinjectWebApiFilterProvider(IKernel kernel)
    {
        _kernel = kernel;
    }

    public IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
    {
        var controllerFilters = actionDescriptor.ControllerDescriptor.GetFilters().Select(instance => new FilterInfo(instance, FilterScope.Controller));
        var actionFilters = actionDescriptor.GetFilters().Select(instance => new FilterInfo(instance, FilterScope.Action));

        var filters = controllerFilters.Concat(actionFilters);

        foreach(var filter in filters)
        {
            _kernel.Inject(filter.Instance);
        }

        return filters;
    }
}

NinjectWebCommon CreateKernel方法

private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

        // Ad Ninject support for Web API.
        GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);

        GlobalConfiguration.Configuration.Services.Add(typeof(IFilterProvider), 
            new NinjectWebApiFilterProvider(kernel));

        RegisterServices(kernel);
        return kernel;
    }

NinjectWebCommon 绑定(bind)

private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<ServiceDbContext>().To<ServiceDbContext>();
        kernel.Bind<IServiceRepository>().To<ServiceRepository>();

        kernel.Bind<CareerDevelopmentDbContext>().To<CareerDevelopmentDbContext>();
        kernel.Bind<ICareerDevelopmentRepository>().To<CareerDevelopmentRepository>();
        kernel.Bind<ICareerDevelopmentService>().To<CareerDevelopmentService>();

        kernel.Bind<IEventLogger>().To<ServiceEventLogger>();
        kernel.Bind<IFilterProvider>().To<NinjectWebApiFilterProvider>().WithConstructorArgument("kernel", kernel);
    }        

最佳答案

我遇到了同样的问题,并以相同的方式配置我的错误处理程序,将其添加到 WebApiConfig.cs 中的过滤器集合中,这意味着它没有被 FilterProvider< 处理 我添加的实现。所以我这样做了:

public class LoggingExceptionFilterAttribute : ExceptionFilterAttribute, IExceptionFilter
{
    // this is what I wanted injected
    private IEmailService emailService;

    public LoggingExceptionFilterAttribute(IEmailService service)
    {
        emailService = service;
    }

    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        // my implementation here
    }
}

然后我在 NinjectWebCommon 中注册了它,如下所示:

kernel.Bind<System.Web.Http.Filters.IExceptionFilter>().To<LoggingExceptionFilterAttribute>().InSingletonScope();

然后在 WebApiConfig 中我意识到我可以获取 DependencyResolver 所以我这样做了:

config.Filters.Add((IFilter)config.DependencyResolver.GetService(typeof(IExceptionFilter)));

现在 Ninject 处理构建我的异常过滤器,我什至可以进行构造函数注入(inject),而不需要 [Inject] 属性,而且我不必将我的 ExceptionFilterAttribute 添加到每个API Controller 。

关于error-handling - WebAPI 自定义 ExceptionFilterAttribute 中的 Ninject 属性注入(inject)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21614139/

相关文章:

c# - 使用 Ninject(或其他一些容器)我如何找出请求服务的类型?

ruby-on-rails - 部署到Heroku时出现ActionView错误,在本地可以正常运行

php - 调用 php 中未定义的方法

Python 为 os.listdir 返回的文件名引发 FileNotFoundError

asp.net-mvc - Fiddler 未从 LINQPad 上的 webClient 捕获本地流量

asp.net - 如何将 DateTime 值发布到 Web API 2 Controller

使用接口(interface)而不是具体类进行 ASP.NET Web API 操作

c# - 使 Entity Framework 实现一个接口(interface)

c# - 没有依赖服务的 DI 服务

python - 从Python异常中删除路径