Внедрить Logger в IExceptionFilter с SimpleInjector - PullRequest
0 голосов
/ 28 августа 2018

Я использую Simple Injector в приложении ASP.NET Core 2.1 WebAPI. У меня есть IExceptionFilter, в котором я хочу записать ошибку. Мой код ниже (работает), но это правильный путь? Похоже, много работы

public class HttpGlobalExceptionFilter : IExceptionFilter
{
    private readonly ILogger logger;

    public HttpGlobalExceptionFilter(Infrastructure.Common.ILogger logger)
    {
        // This is my own logger, implemented along the lines as mentioned here:
        // https://stackoverflow.com/questions/41243485/
        this.logger = logger;
    }

    public void OnException(ExceptionContext context)
    {
        // Irrelevant stuff
        // ...

        var error = $"An error occured: {context.Exception.Message}";
        this.logger.LogError(error);
        context.ExceptionHandled = true;
    }
}

В моем Startup.cs ConfigureServices () у меня есть:

services.AddMvc(options =>
{
    options.Filters.Add(new SimpleInjectorExceptionFilterDispatcher(
        this.container.GetInstance<IExceptionFilter>));
    // ...
});

вместо

services.AddMvc(options =>
{
    options.Filters.Add<HttpGlobalExceptionFilter>();
    // ...
});

В моих привязках:

container.Register<IExceptionFilter, HttpGlobalExceptionFilter>();

Наконец, диспетчер:

public sealed class SimpleInjectorExceptionFilterDispatcher : IExceptionFilter
{
    private readonly Func<IExceptionFilter> exceptionFilterFunc;

    public SimpleInjectorExceptionFilterDispatcher(
        Func<IExceptionFilter> exceptionFilterFunc)
    {
        this.exceptionFilterFunc = exceptionFilterFunc;
    }

    public void OnException(ExceptionContext context)
    {
        this.exceptionFilterFunc.Invoke().OnException(context);
    }
}

Это способ заставить Simple Injector работать с различными компонентами ASP.NET? Это сложная установка, и я бы предпочел иметь что-то более простое, чтобы все разработчики могли легко понять код.

Кроме того, могу ли я полностью избежать Microsoft DI и использовать Simple Injector (и ожидать более простых конфигураций?)

Ссылки:

Простой инжектор добавляет зависимость в пользовательские фильтры глобальной аутентификации и промежуточное ПО OWIN OAuthAuthorizationServerProvider

Простой инжектор: зарегистрируйте ILogger с помощью ILoggerFactory.CreateLogger ()

1 Ответ

0 голосов
/ 28 августа 2018

В случае, если зависимости HttpGlobalExceptionFilter (в настоящее время ILogger) являются одиночными, вы можете упростить свое решение, исключив SimpleInjectorExceptionFilterDispatcher. Это уменьшит решение до следующего:

options.Filters.Add(new HttpGlobalExceptionFilter(new LoggerAdapter()));

Это создает фильтр и его зависимости вручную. Вы также можете разрешить это из контейнера. Чтобы убедиться, что вы случайно не создаете зависимостей Captive , вы должны убедиться, что вы зарегистрировали HttpGlobalExceptionFilter как Singleton:

container.RegisterSingleton<HttpGlobalExceptionFilter>();

services.AddMvc(options =>
{
    options.Filters.Add(this.container.GetInstance<HttpGlobalExceptionFilter>());
});

Вместо использования фильтров MVC вы также можете перейти на один уровень вверх и определить компонент промежуточного программного обеспечения и подключить его, как описано здесь в документации по Simple Injector. Это еще больше упрощает регистрацию, хотя может усложнить вашу реализацию в зависимости от ваших конкретных потребностей.

Это означает переписывание вашего HttpGlobalExceptionFilter в компонент промежуточного программного обеспечения. Это может выглядеть примерно так:

public sealed class HttpGlobalExceptionMiddleware
    : Microsoft.AspNetCore.Http.IMiddleware
{
    private readonly Infrastructure.Common.ILogger logger;

    public HttpGlobalExceptionMiddleware(ILogger logger) =>
        this.logger = logger;

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        try
        {
            await next(context);
        }
        catch (Exception ex)
        {
            var error = $"An error occured: {ex.Message}";
            this.logger.LogError(error);            
            throw;
        }
    }
}

Используя метод расширения UseMiddleware Simple Injector, вы можете зарегистрировать его в Simple Injector и одновременно добавить его в промежуточный конвейер ASP.NET Core:

app.UseMiddleware<HttpGlobalExceptionMiddleware>(container);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...