我在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: Register ILogger<T> by using ILoggerFactory.CreateLogger<T>()
答案 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);