我正在尝试使用 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/