为什么IServiceCollection.AddScoped <TService,TImplementation>无法获得TImplementation?

问题描述

这是在.net core 3.1上运行的演示 当通过方法provider.GetrequiredService()构建对象时,它将调用HomeController的构造函数。显然,HomeController的构造函数必须在其中输入一个对象,该对象是“ GreetingService”生成的实例。

在从容器创建对象的过程中,生成“ GreetingService”的实例似乎是必须的并且自然的。但是为什么我们不能调用方法provider.GetrequiredService()来获取实例?

using System;
using Microsoft.Extensions.DependencyInjection;

namespace DIDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceCollection service = new ServiceCollection();
            service.AddScoped<IGreetingService,GreetingService>();
            service.AddScoped<HomeController>();
            var provider = service.BuildServiceProvider();
            //var result = provider.GetrequiredService<GreetingService>();  why wrong
            var result = provider.GetrequiredService<HomeController>();
            result.Hello("Bob");
        }
    }

    public class HomeController
    {
        private readonly IGreetingService _greetingService;
        public HomeController(IGreetingService greetingService)
        {
            _greetingService = greetingService;
        }

        public string Hello(string name) => _greetingService.Greet(name);
    }

    public interface IGreetingService
    {
        string Greet(string name);
    }

    public class GreetingService : IGreetingService
    {
        public string Greet(string name)
        {
            Console.WriteLine($"Hello,{name}");
            return "Done";
        }
    }
}

解决方法

这是因为您已注册接口-IGreetingService,而不是类`GreetingService。下一步将起作用:

var result = provider.GetRequiredService<IGreetingService>();  

如果您查看具有2个通用参数的Add..方法签名,您将看到next

public static IServiceCollection AddScoped<TService,TImplementation> (this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class where TImplementation : class,TService; 

因此在您GreetingService的情况下,TServiceIGreetingService,而TImplementationGreetingService,如文档所述:

TService中指定类型的范围服务和TImplementation中指定的实现类型添加到指定的IServiceCollection

对于单个通用参数版本:

public static IServiceCollection AddScoped<TService> (this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TService : class;

TService中指定类型的范围服务添加到指定的IServiceCollection中。