我正在跟踪一个现有的代码库,试图理解 DI 生命周期,在下面的代码中,我们有一个注册为单例的 Factory 类,它从字典中返回一个实例(如果存在),或者创建一个新的瞬态实例并返回它同时将其存储在字典中。
我的问题是在工厂内创建和存储的瞬态实例是否会开始像单例一样运行?这是一个好的编码方法吗?
我的程序.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddHostedService<Consumer>()
.AddSingleton<IPipelineFactory, PipelineFactory>()
.AddTransient<IPipeline, Pipeline>();
var app = builder.Build();
app.MapGet("/", (IPipelineFactory pipelineFactory) =>
{
return $"Total pipelines: {pipelineFactory.GetPipelineCount()}";
});
app.Run();
我的工厂实施,
public class PipelineFactory : IPipelineFactory
{
private readonly Dictionary<int, IPipeline> _pipelines = new();
private readonly IServiceProvider _serviceProvider;
public PipelineFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IPipeline GetPipeline(int pipelineId)
{
if (!_pipelines.ContainsKey(pipelineId))
{
using var scope = _serviceProvider.CreateScope();
_pipelines.Add(pipelineId, scope.ServiceProvider.GetRequiredService<IPipeline>());
}
return _pipelines[pipelineId];
}
public int GetPipelineCount()
{
return _pipelines.Count;
}
}
我的问题是在工厂内创建和存储的瞬态实例是否会开始像单例一样运行?
是的,有效。
这是一个好的编码方法吗?
可以说——不。这在某种程度上是可以容忍的,但我强烈建议重新考虑这种方法。基本上,您依赖于管道在内部不使用任何范围服务的事实。如果您没有作用域依赖项,则无需创建作用域 (
_serviceProvider.CreateScope()
)。
如果您执行以下操作:
if (!_pipelines.ContainsKey(pipelineId))
{
using var scope = _serviceProvider.CreateScope();
_pipelines.Add(pipelineId, scope.ServiceProvider.GetRequiredService<IPipeline>());
}
有几个问题:
另请参阅: