【问题标题】:Inject Logger in IExceptionFilter with SimpleInjector使用 SimpleInjector 在 IExceptionFilter 中注入 Logger
【发布时间】:2018-08-28 16:58:13
【问题描述】:

我在 ASP.NET Core 2.1 WebAPI 应用程序中使用 Simple Injector。我有一个 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(并期望更简单的配置?)

参考资料:

Simple Injector inject dependency into custom global authentication filters and OWIN middle ware OAuthAuthorizationServerProvider

Simple Injector: Register ILogger<T> by using ILoggerFactory.CreateLogger<T>()

【问题讨论】:

    标签: c# asp.net-core simple-injector


    【解决方案1】:

    如果HttpGlobalExceptionFilter 的依赖项(当前为ILogger)是单例的,您可以通过删除SimpleInjectorExceptionFilterDispatcher 来简化您的解决方案。这会将解决方案简化为以下内容:

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

    这会手动构建过滤器及其依赖项。您也可以从容器中解决它。为确保您不会意外创建Captive Dependencies,您应确保将HttpGlobalExceptionFilter 注册为Singleton

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

    除了使用 MVC 过滤器之外,您还可以更上一层并定义一个中间件组件并将其连接起来,如 Simple Injector 文档中的here 所述。这进一步简化了注册,尽管它可能会使您的实施复杂化,具体取决于您的具体需求。

    这意味着将您的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;
            }
        }
    }
    

    使用Simple Injector的UseMiddleware扩展方法,可以注册Simple Injector,同时添加到ASP.NET Core的中间件管道中:

    app.UseMiddleware<HttpGlobalExceptionMiddleware>(container);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      • 2012-10-21
      • 2012-04-23
      • 2014-12-13
      • 2017-01-09
      • 1970-01-01
      相关资源
      最近更新 更多