使用SimpleInjector

时间:2018-08-28 16:58:14

标签: c# asp.net-core 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(并期待更简单的配置?)

参考文献:

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

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

1 个答案:

答案 0 :(得分: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);