上下文:Owin(自主)+ WebApi + UseAutofacMiddleware + UseAutofacWebApi
我要做的是:
在app启动容器中注册ILog
实例。
对于每个请求,注册一个包含“root”实例的新ILog
实例,以便每个中间件和/或每个请求服务都可以使用它。
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterInstance(log).As<ILog>();
containerBuilder.Register(ctx => {
var rootLog = ctx.Resolve<ILog>();
return new PrependStringLog(rootLog, "request: ");
}).InstancePerRequest();
然而,Autofac在实例化构造函数中具有ILog
的中间件时会抱怨循环依赖。
如果我将“root log”命名为“root log”并使用给定名称解析,则一切都按预期工作。
containerBuilder.RegisterInstance(log)
.Named("root", typeof(ILog));
containerBuilder.Register(ctx => {
var rootLog = ctx.ResolveNamed<ILog>("root");
return new PrependStringLog(rootLog, "request: ");
}).InstancePerRequest();
我是否被迫使用命名实例来使其工作?
答案 0 :(得分:1)
Autofac 在组件请求服务时使用最新的注册服务。
在您的情况下,最新注册的ILog
是lambda表达式:
containerBuilder.Register(ctx => {
var rootLog = ctx.Resolve<ILog>();
return new PrependStringLog(rootLog, "request: ");
}).InstancePerRequest();
这个lambda表达式请求ILog
这是 Autofac 正在尝试构建的内容:这就是它检测循环依赖的原因。
避免循环依赖的最简单方法是让您的注册不依赖于自身。这是通过解析命名的ILog
来做的,这是我推荐的解决方案。
在您的情况下,您也可以直接使用根日志而不解析它:
containerBuilder.RegisterInstance(rootLog).As<ILog>();
containerBuilder.Register(ctx => {
return new PrependStringLog(rootLog, "request: ");
}).InstancePerRequest();