Я пишу собственный атрибут ErrorHandler для моего проекта MVC. Я хотел бы внедрить реализацию 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 в свойство Logger типа CustomHandleErrorAttribute
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: }
Потратил день на это, узнал много нового о внедрении зависимости, и это здорово, но что я тут делаю не так?