请记住.NET dependency injection guidelines条建议:
- 避免使用服务定位器模式.例如,当您可以使用DI时,不要调用GetService来获取服务实例.
- 另一个需要避免的服务定位器变体是注入在运行时解决依赖关系的工厂.这两种实践混合了控制倒置策略.
.NET文档表明我们可以通过IServiceProvider
或IServiceScopeFactory
消费范围服务,就像here或here一样,例如
public class ConsumeScopedServiceHostedService: BackgroundService
{
// ...
public ScopedProcessingService(IServiceProvider services) { // ... }
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using (var scope = _services.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<FooDbContext>();
// ...
}
}
另一种方式是大约variation of a factory个,例如
public class ConsumeFactoryHostedService: BackgroundService
{
// ...
public ConsumeFactoryHostedService(Func<FooDbContext> dbContextFactory) { // ... }
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using (var dbContext = _dbContextFactory()) { // ... }
}
}
但这两种实现不是都违背了前面提到的建议吗?可能对于许多情况来说"没关系"(尤其是对于"简单"的微服务),但我仍然对"最正确"的方式感兴趣-那么,我们是否应该使用另一种模式呢?How should we use short-lived 100 instances in an 101?