【问题标题】:how AddSingleton<TService, TImplementation>() worksAddSingleton<TService, TImplementation>() 如何工作
【发布时间】:2021-03-13 21:31:44
【问题描述】:

我是依赖注入的新手,我在一个 asp.net 核心项目中遇到过这行代码

services.AddSingleton<TService, TImplementation>()

我很困惑'TService,TImplementation'是用来告诉编译器将返回或/并传递给我的方法的泛型类型我是对的吗?但是有问题的方法不采用我所缺少的任何参数?该方法不应该是这样的吗:

services.AddSingleton<TService, TImplementation>(TService a,TImplementation b)

这个问题已经被问到AddSingleton<>() vs AddSingleton(),但我并不清楚答案,有人可以解释一下这是如何工作的吗?

【问题讨论】:

  • 您在链接问题的答案中到底有什么不明白的地方?在不带参数的变体中,当你请求TService接口时,依赖注入框架会为你创建(或获取)实现对象TImplementation
  • 它的工作方式更像是声明式的,通常服务类型是必需的(服务类型是您在设计时使用的类型或称为设计-时间依赖类型)。实现类型是运行时类型,它的实例被创建并注入到服务类型引用的位置(在构造函数、属性等中)。它只需要类型映射来完成它的工作。有时,创建实例需要一个工厂,因此您可以为其提供一个工厂。最后,有时您已经有了实例,所以只需注册它(而不是实现类型)。
  • 有一种特殊情况,服务类型和实现类型相同。这是您使用AddSingleton&lt;T&gt;AddSingleton(someInstance) 的情况。服务类型(用于后一种用法)派生自someInstance 的类型(编译器支持的一个特性)。

标签: c# asp.net-core


【解决方案1】:

此方法接受两个类型参数TServiceTImplementation,以及零个方法参数。

此方法的完整签名和实现类似于

public static IServiceCollection AddSingleton<TService, TImplementation>(this IServiceCollection services)
    where TService : class
    where TImplementation : class, TService
{
    if (services == null)
        throw new ArgumentNullException(nameof(services));
    return services.AddSingleton(typeof(TService), typeof(TImplementation));
}

类型参数告诉您作为开发人员,您应该期望 IoC 容器对 TService 的任何解析都将返回 TImplementation 的单个实例。 where TImplementation : class, TService 的类型安全检查表明返回的实际类必须实现(或者是)TService

如何创建实际的TImplementation,取决于容器,并且取决于TImplementation 的构造函数上的零个或多个构造函数参数。

您的问题“该方法不应该是这样的吗”,通常会得到“不”的答案。原因是该签名要求您有两个实际对象(实际上可能一个传递了两次)已经构造,这通常首先破坏了依赖注入的目的。

类型参数不必与实际的方法参数相对应,尽管它们经常(通常)这样做。在这种特殊情况下,类型参数本身作为 Type 类型的实际参数传递给另一个方法,然后 IoC 实现的其余部分使用这些参数来创建正确的对象。

那么他们为什么要这样做而不只是拥有services.AddSingleton(Type serviceType, Type implementationType)?。答案在于类型安全。此签名不是类型安全的,因为您可以调用 services.AddSingleton(typeof(Animal), typeof(House)),这没有意义并且会在运行时失败。相反,services.AddSingleton&lt;Animal, House&gt;() 甚至无法编译。

【讨论】:

    猜你喜欢
    • 2020-09-16
    • 2022-10-07
    • 1970-01-01
    • 2018-06-19
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 2022-08-22
    相关资源
    最近更新 更多