我正在使用ASP.NET Core。我是Autofac的新手。
第三方库(NLog)将我的Foo
对象用于应用程序的生命周期,因此它实际上变成了单例,我无法改变它。问题是Foo
有一个作用域依赖,它实际上也变成了一个单例(一个强制依赖)。
在related question中,我被告知将依赖项更改为Func<Dependency>
,因此会在每个请求上创建一个新实例。内置容器不支持Func<>
,因此我使用的是Autofac。
我的类型:
public class Foo
{
public Foo(Func<IMyContext> contextFactory) { _contextFactory = contextFactory; }
private readonly Func<IMyContext> _contextFactory;
public void doSomething() { /* shown below */ }
}
我的Startup
:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddScoped<IMyContext, MyContext>();
services.AddSingleton<Foo>();
var builder = new ContainerBuilder();
builder.Populate(services);
return new AutofacServiceProvider(builder.Build());
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory log)
{
var foo = app.ApplicationServices.GetService<Foo>();
ConfigureNLog(foo); // effectively becomes a singleton, and I can't change that
// ...
}
要在请求期间对此进行测试,请记录实例的哈希码:
public class Foo
{
// ...
public void doSomething()
{
using (var context = _contextFactory())
{
_logger.log(context.GetHashCode()); // should be unique on each request
}
}
}
我希望每个请求都有一个唯一的哈希码,因为依赖项是通过Func<>
工厂创建的。但它们总是一样的!因此,每个请求都是相同的实例。
我该如何解决这个问题?
答案 0 :(得分:1)
更改上下文的注册,如下所示:
services.AddTransient<IMyContext, MyContext>();
每次MyContext
调用Foo
时,这将为您提供Func<IMyContext>
的新实例。每次在这里都很重要,因为这意味着如果在同一个HTTP请求期间调用Func
10次,将创建10个不同的实例。
也许我用错误的方式阅读了它,但是我认为你想要达到的目的是:你希望注入Func<IMyContext>
的{{1}}解析为{{1}的同一个实例每个HTTP请求。
我认为这是不可能的,并且它不是特定于Autofac的问题。
原因是注入Foo
的{{1}}与根生存期范围相关联 - 因为MyContext
本身是从根容器创建的。这意味着Func<IMyContext>
不Foo
都不知道为每个HTTP请求创建的潜在嵌套生命周期范围。
您可以使用的唯一解决方案是,每次容器解析时都会创建Foo
的新实例。
这是否符合您的要求?