使用 SimpleInjector 在 IExceptionFilter 中注入 Logger
Inject Logger in IExceptionFilter with SimpleInjector
我在 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:
//
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(并期望更简单的配置?)
参考文献:
如果 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.NETCore的中间件管道中:
app.UseMiddleware<HttpGlobalExceptionMiddleware>(container);
我在 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:
//
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(并期望更简单的配置?)
参考文献:
如果 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.NETCore的中间件管道中:
app.UseMiddleware<HttpGlobalExceptionMiddleware>(container);