【发布时间】:2017-08-02 07:53:55
【问题描述】:
我正在使用 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<> 工厂创建的。但他们总是一样的!所以每个请求都是同一个实例。
我该如何解决这个问题?
【问题讨论】:
-
@CodeCaster 该示例不共享任何远程接近 OP 描述的内容。没有生命周期范围,每个服务都注册为瞬态服务,并且没有捕获应该创建上下文的服务的单个实例。
-
@CodeCaster 您的代码 sn-p 帮助很大。您可以添加为答案以便我接受吗?也感谢你向我介绍了非常酷的 dotnetfiddle。
-
嗯,我认为@Mickaël 有一点,这个问题与你之前的问题没有太大关系,所以我可以看到他的评论来自哪里 - 我知道这个问题的背景,他没有。随意接受他的回答。 :)
-
@CodeCaster 您的代码可以正常工作,只是我需要将您的 ctor 注入 arg 从
Func<Dependency>更改为Func<Owned<Dependency>>。现在它完全按预期工作。我不明白为什么,但是有了那个小模块,你的代码就很好用。
标签: .net asp.net-core autofac