我正在为我的MVC项目编写自定义的ErrorHandler属性。我想将EventViewerLogger的实现注入该属性。
我正在使用Ninject 2.2,它适用于其他功能,例如注入存储库和通过控制器构造函数的聚合服务。
我明白我不能通过构造函数将某个类的实现注入属性,因此我必须将它注入属性的属性中。
接口如下:
namespace Foo.WebUI.Infrastructure
{
public interface ILogger
{
void Log(Exception e);
}
}
事件查看器记录器实现
namespace Foo.WebUI.Infrastructure
{
/// <summary>
/// Logs exceptions into the Windows Event Viewer
/// </summary>
public class EventViewerLogger: ILogger
{
private EventViewerLogger _logger = null;
EventViewerLogger()
{
_logger = new EventViewerLogger();
}
public void Log(Exception e)
{
_logger.Log(e);
}
}
}
以下是错误处理程序的代码:
namespace Foo.WebUI.Handlers
{
/// <summary>
/// Custom error handler with an interface to log exceptions
/// </summary>
public class CustomHandleErrorAttribute: HandleErrorAttribute
{
[Inject]
public ILogger Logger { get; set; }
// Default constructor
public CustomHandleErrorAttribute():base() { }
public override void OnException(ExceptionContext filterContext)
{
Logger.Log(filterContext.Exception);
base.OnException(filterContext);
}
}
}
在global.asax中我注册了处理程序和Ninject。
protected void Application_Start()
{
IKernel kernel = new StandardKernel(new NinjectInfrastructureModule());
}
最后,我有一个自定义过滤器提供程序
namespace Foo.WebUI.Infrastructure
{
public class NinjectFilterProvider: FilterAttributeFilterProvider
{
private readonly IKernel kernel;
public NinjectFilterProvider(IKernel kernel)
{
this.kernel = kernel;
}
public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
var filters = base.GetFilters(controllerContext, actionDescriptor);
// Iterate through all the filters and use Ninject kernel to serve concrete implementations
foreach (var filter in filters)
{
kernel.Inject(filter.Instance);
}
return filters;
}
}
}
当我启动应用程序时,我得到以下异常:
激活路径: 2)将依赖ILogger注入属性CustomHandleErrorAttribute类型的Logger 1)请求CustomHandleErrorAttribute
建议: 1)确保实现类型具有公共构造函数。 2)如果已实现Singleton模式,请改为使用与InSingletonScope()的绑定。
Source Error:
Line 27: foreach (var filter in filters)
Line 28: {
Line 29: kernel.Inject(filter.Instance);
Line 30: }
花了一天时间,学到很多关于依赖注射的知识,这很好,但我在这里做错了什么?
答案 0 :(得分:3)
Ninject.Web.Mvc具有内置的名为“BindFilter”的功能,它允许您将属性(需要一些或不带构造函数的args)映射到过滤器(其中注入了构造函数args)。此外,您可以使用它来复制属性中的值,并根据需要将它们作为构造函数args注入过滤器。它还允许您将过滤器的范围更改为每个操作或每个控制器等,以便实际重新实例化(正常操作过滤器不会根据请求重新实例化)。
以下是example我如何使用它来执行UoW动作过滤器。