You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中依赖注入消费的实例引用及执行顺序疑问

C#中依赖注入消费的实例引用及执行顺序疑问

嘿,这个问题问得挺细致的,我来给你掰扯清楚~

首先你完全不用担心会搞混两个g1,因为它们指向的是同一个Garage实例,根本不存在“二选一”的情况。咱们一步步拆解执行顺序和引用关系:

1. DI容器创建实例的流程

当你的代码需要用到Car实例时(比如通过DI注入或者直接从容器解析),容器会按以下步骤走:

  • 先看Garage的注册是Scoped,所以会在当前作用域(比如ASP.NET Core里的单个HTTP请求)内查找有没有已存在的Garage实例。如果没有,就新建一个;如果有,直接复用这个实例。
  • 把拿到的这个Garage实例,作为参数传给Car的构造函数(也就是你写的public class Car(Garage g1)里的g1参数)。

2. 构造函数里的赋值逻辑

你在构造函数里写的private readonly Garage g1 = g1;,其实是把构造函数参数里的Garage实例引用,赋值给了类的私有只读字段g1。这时候,参数g1和字段g1指向的是内存里同一个对象——打个比方,就像两个人拿着同一把钥匙,都能打开同一扇门。

如果不信的话,你可以在构造函数里加两行代码验证:

public class Car(Garage g1)
{
    private readonly Garage g1 = g1;
    public Car()
    {
        Console.WriteLine($"参数g1的HashCode: {g1.GetHashCode()}");
        Console.WriteLine($"字段g1的HashCode: {this.g1.GetHashCode()}");
    }
    // ... 其他代码
}

运行后你会发现两个HashCode完全一样,这就实锤了它们是同一个实例。

3. 方法调用时的引用

当你调用ModifyCarAndStoreInGarage方法时,里面的g1.AddCar(car),用的就是你私有字段里的g1——而这个字段的引用,就是当初DI容器注入进来的那个Garage实例。所以整个过程里,自始至终都是同一个Garage对象在干活。

补充:Scoped的作用范围

因为你注册Garage用的是AddScoped,所以在同一个作用域内(比如同一个HTTP请求),不管是注入到Car里,还是注入到其他类里,拿到的都是同一个Garage实例。只有当作用域结束(比如请求处理完),这个实例才会被释放。

总结一下:不存在“方法不知道引用哪个g1”的问题,所有的g1都是同一个实例的引用,执行顺序就是DI先解析依赖注入构造函数,构造函数把引用存到字段,方法调用时直接用这个字段的引用就行~

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 08:44:35