如何配置SimpleInjector来解析LogMiddleware的Invoke方法依赖,比如IMessageService?
据我所知,Asp.net核心使用HttpContext.RequestServices(IServiceProvider)来解析依赖关系,我将SimpleInjector容器设置为HttpContext.RequestServices属性但是没有用。我想动态更改ServiceProvider,因为每个租户都应该有一个容器。
public class LogMiddleware
{
RequestDelegate next;
private readonly ILogger log;
public LogMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
{
this.next = next;
this.log = loggerFactory.CreateLogger<LogMiddleware>();
}
public async Task Invoke(HttpContext context, IMessageService messageService)
{
await context.Response.WriteAsync(
messageService.Format(context.Request.Host.Value));
}
}
public interface IMessageService
{
string Format(string message);
}
public class DefaultMessageService : IMessageService
{
public string Format(string message)
{
return "Path:" + message;
}
}
答案 0 :(得分:2)
您可以按照以下方式使用LogMiddleware
课程:
applicationBuilder.Use(async (context, next) => {
var middleware = new LogMiddleware(
request => next(),
applicationBuilder.ApplicationServices.GetService<ILoggerFactory>());
await middleware.Invoke(context, container.GetInstance<IMessageService>());
});
但是我建议你稍微改变你的中间件类。将运行时数据(next()
委托)移出构造函数(自components should not require runtime data during construction起),并将IMessageService
依赖项移动到构造函数中。并将ILoggerFactory
替换为ILogger
依赖项,因为注入构造函数应do no more than store its incoming dependencies(或将ILogger
替换为your own application-specific logger abstraction instead)。
您的中间件类将如下所示:
public sealed class LogMiddleware
{
private readonly IMessageService messageService;
private readonly ILogger log;
public LogMiddleware(IMessageService messageService, ILogger log) {
this.messageService = messageService;
this.log = log;
}
public async Task Invoke(HttpContext context, Func<Task> next) {
await context.Response.WriteAsync(
messageService.Format(context.Request.Host.Value));
await next();
}
}
这允许您按如下方式使用中间件:
var factory = applicationBuilder.ApplicationServices.GetService<ILoggerFactory>();
applicationBuilder.Use(async (context, next) => {
var middleware = new LogMiddleware(
container.GetInstance<IMessageService>(),
factory.CreateLogger<LogMiddleware>());
await middleware.Invoke(context, next);
});
或者,如果您在Simple Injector中注册了ILogger
(或您的自定义日志记录抽象),您可以执行以下操作:
applicationBuilder.Use(async (context, next) => {
var middleware = container.GetInstance<LogMiddleware>();
await middleware.Invoke(context, next);
});
答案 1 :(得分:0)
您的代码存在两个问题。
public class DefaultMessageService : IMessageService { public string Format(string message) { return "Path:" + message; } }
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); services.AddSingleton<IMessageService>(new DefaultMessageService()); }