Joe*_*nos 3 c# dependency-injection .net-core
在 .NET Core Console 应用程序中,我想使用内置的依赖注入,包括IDisposable
链中对象的自动处理。在 ASP.NET Core 中,每个请求都会创建和处理对象,这似乎是合理的。
但是在控制台应用程序中,我必须构建服务提供者,然后通过从提供者检索链中的第一项并运行来启动它:
class Program {
static void Main() {
using var serviceProvider = new ServiceCollection()
.AddTransient<Program>()
.AddTransient<Repository>()
.AddTransient<MyContext>()
.BuildServiceProvider();
serviceProvider.GetService<Program>().Go();
}
private readonly Repository _repo;
public Program(Repository repo) => _repo = repo;
public void Go() => _repo.Go();
}
public class Repository : IDisposable {
private readonly MyContext _context;
public Repository(MyContext context) => _context = context;
public void Go() => Console.WriteLine("Go!");
public void Dispose() => Console.WriteLine("Repository Disposed!");
}
public class MyContext : DbContext {
public override void Dispose() {
base.Dispose();
Console.WriteLine("MyContext Disposed!");
}
}
Run Code Online (Sandbox Code Playgroud)
当serviceProvider
被处置时,其余的也会被处置:
Go!
Repository Disposed!
MyContext Disposed!
Run Code Online (Sandbox Code Playgroud)
如果我想在循环中或使用计时器运行该过程,则在处理服务提供者本身之前,不会处理任何内容:
for (int i = 0; i < 3; ++i)
{
serviceProvider.GetService<Program>().Go();
}
Go!
Go!
Go!
Repository Disposed!
MyContext Disposed!
Repository Disposed!
MyContext Disposed!
Repository Disposed!
MyContext Disposed!
Run Code Online (Sandbox Code Playgroud)
如果我每次都处理并重新创建服务提供者,我会得到我想要的结果:
for (int i = 0; i < 3; ++i)
{
using var serviceProvider = new ServiceCollection()
.AddTransient<Program>()
.AddTransient<Repository>()
.AddTransient<MyContext>()
.BuildServiceProvider();
serviceProvider.GetService<Program>().Go();
}
Go!
Repository Disposed!
MyContext Disposed!
Go!
Repository Disposed!
MyContext Disposed!
Go!
Repository Disposed!
MyContext Disposed!
Run Code Online (Sandbox Code Playgroud)
我的问题:像这样一遍又一遍地构建和处理提供程序可以吗?我正在考虑每隔几秒钟无限期地在计时器上执行此操作。这样做是否是一个昂贵的过程,有没有更好的方法,而不必手动处理整个链中的对象?
或者这可能是 ASP.NET Core 在幕后所做的事情,为每个请求重新创建提供程序?
创建一个范围,从中解决所有依赖项,然后处置该范围。看起来像这样:
using var serviceProvider = new ServiceCollection()
.AddTransient<Program>()
.AddTransient<Repository>()
.AddTransient<MyContext>()
.BuildServiceProvider();
for (int i = 0; i < 3; ++i)
{
using var scope = serviceProvider.CreateScope();
scope.ServiceProvider.GetService<Program>().Go();
}
Run Code Online (Sandbox Code Playgroud)
当服务范围本身被释放时,由服务范围创建的所有范围和瞬态服务都会被释放。在这个例子中,所有涉及的服务都注册为瞬态,这意味着每次Program
请求时都会创建新实例。如果您Program
要从同一服务范围多次请求,您将获得所有必需注册服务的多个实例。这些实例中的每一个都由服务范围跟踪并与服务范围一起处理。
归档时间: |
|
查看次数: |
284 次 |
最近记录: |