C# 如果我使用ServiceProvider接口来解析.NET Core中的属性以进行依赖项注入,这是否不好

C# 如果我使用ServiceProvider接口来解析.NET Core中的属性以进行依赖项注入,这是否不好,c#,.net,asp.net-core,dependency-injection,.net-core,C#,.net,Asp.net Core,Dependency Injection,.net Core,如果我使用ServiceProvider接口来解析.NET Core中的属性以进行依赖项注入,这是否不好 假设我有以下几点 private readonly IRecipeRepository _recipeRepository; private readonly IMediaResource _resourceUpload; private readonly IAWSMedia _awsMedia; 然后再这样做 public RecipeService(IS

如果我使用ServiceProvider接口来解析.NET Core中的属性以进行依赖项注入,这是否不好

假设我有以下几点

    private readonly IRecipeRepository _recipeRepository;
    private readonly IMediaResource _resourceUpload;
    private readonly IAWSMedia _awsMedia;
然后再这样做

    public RecipeService(IServiceProvider service)
    {
        _recipeRepository = service.GetService<IRecipeRepository>();
        _resourceUpload = service.GetService<IMediaResource>();
        _awsMedia = service.GetService<IAWSMedia>();
    }

第一位代码称为服务定位器反模式,这是您不应该做的事情。但是,您的问题的答案取决于您未提供的上下文

在大多数情况下,不应该只注入
IServiceProvider
。然而,在某些场景中,您别无选择,只能:即处理单例范围内的事物。如果您有一个单例类型的类,
IHostedService
实现等,那么除了其他单例范围的服务之外,您不能注入任何东西。如果您需要不同范围内的内容,如
DbContext
,则只能通过注入
IServiceProvider
并创建一个范围来实现:

using (var scope = _serviceProvider.CreateScope())
{
    var foo = scope.ServiceProvider.GetRequiredService<Foo>();
    // do something with foo;
}
使用(var scope=\u serviceProvider.CreateScope())
{
var foo=scope.ServiceProvider.GetRequiredService();
//用foo做点什么;
}

但是,请记住,检索到的实例与作用域绑定。换句话说,当
using
语句关闭时,它将被释放。因此,您需要在该范围内对该实例执行任何操作。您不能在类上设置实例变量,以后再尝试使用它,因为您将得到一个
ObjectDisposedException

第一位代码称为服务定位器反模式,这是您不应该做的事情。但是,您的问题的答案取决于您未提供的上下文

在大多数情况下,不应该只注入
IServiceProvider
。然而,在某些场景中,您别无选择,只能:即处理单例范围内的事物。如果您有一个单例类型的类,
IHostedService
实现等,那么除了其他单例范围的服务之外,您不能注入任何东西。如果您需要不同范围内的内容,如
DbContext
,则只能通过注入
IServiceProvider
并创建一个范围来实现:

using (var scope = _serviceProvider.CreateScope())
{
    var foo = scope.ServiceProvider.GetRequiredService<Foo>();
    // do something with foo;
}
使用(var scope=\u serviceProvider.CreateScope())
{
var foo=scope.ServiceProvider.GetRequiredService();
//用foo做点什么;
}

但是,请记住,检索到的实例与作用域绑定。换句话说,当
using
语句关闭时,它将被释放。因此,您需要在该范围内对该实例执行任何操作。您不能在类上设置实例变量,以后再尝试使用它,因为您将得到一个
ObjectDisposedException

如果您必须注入许多依赖项并且必须在多个位置执行,请考虑单元测试的后果。..@ta.speot.is+1,您可以考虑使用聚合服务。在这种情况下,我认为它不是主要基于意见的,因为演示的代码示例是一个众所周知的、有良好文档的反模式,称为服务定位器,正如@ KirkLarkin正确引用的那样。更确切地说,这个问题是一个重复。想想单元测试的后果。@ TA.Seop.Is+1,如果你必须注入许多依赖性,你必须在多个地方做它,你可以考虑使用聚合服务。在这种情况下,我认为它不是主要基于意见的,因为演示的代码示例是一个众所周知且有良好文档记录的反模式,称为服务定位器,正如@KirkLarkin正确引用的那样。相反,这个问题是重复的。