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

两种返回类实例方式的差异及服务提供者实现意义的技术咨询

两种返回类实例方式的差异及服务提供者实现意义的技术咨询

兄弟,我太懂你现在的疑惑了——直接new一个实例看起来简单又直接,为啥要绕这么大弯用依赖注入的服务提供者那套?咱们来好好拆解下这两种方式的差异,以及后者到底有啥实际价值。

先把你的代码贴出来方便对照:

public class UdpFactory : IUdpFactory { 
    public int Port; 
    public ObservableCollection<string> Log; 

    public IUdpListener CreateUdpListener(int port, ObservableCollection<string> lgm) { 
        var services = new ServiceCollection(); 
        var isServer = Environment.GetEnvironmentVariable("DefineConstants")?.Contains("Server"); 

        if (isServer.HasValue && isServer.Value) { 
            return new UDPServer(); 
            //services.AddTransient<IUdpListener, UDPServer>(); 
        } else { 
            return new UDPServerClnt(); 
            //services.AddTransient<IUdpListener, UDPServerClnt>(); 
        } 

        //var serviceProvider = services.BuildServiceProvider(); 
        //return serviceProvider.GetRequiredService<IUdpListener>(); 
    } 
}

先说说你现在直接new实例的方式的局限

  • 耦合度拉满:你的UdpFactory现在直接绑定了UDPServer和UDPServerClnt的具体实现,以后要是想换个新的IUdpListener实现(比如UdpAdvancedServer),你必须修改UdpFactory里的代码,完全违反了开闭原则——对扩展开放,对修改关闭。
  • 手动处理依赖是噩梦:如果哪天你的UDPServer构造函数需要新增依赖(比如ILogger<UDPServer>、IConfiguration或者其他业务服务),你所有直接new UDPServer()的地方都得手动传递这些依赖项,要是依赖层级深了,改起来能让你头大。
  • 生命周期全靠自己硬写:要是你以后想把IUdpListener改成单例实例(整个应用里只存在一个)或者作用域实例(比如每个请求一个),直接new的话你得自己写一堆逻辑去管理实例的创建和销毁,很容易写出隐蔽的bug。

再看注释里的服务提供者(DI容器)方式的核心价值

  • 彻底解耦:UdpFactory只需要依赖IUdpListener接口和DI容器,具体的实现类是在ServiceCollection里注册的。以后要换实现,只需要改注册代码(比如把AddTransient<IUdpListener, UDPServer>()换成AddTransient<IUdpListener, UdpAdvancedServer>()),完全不用动UdpFactory的核心逻辑。
  • 自动注入依赖省老事:DI容器会自动处理IUdpListener实现类的所有依赖项。比如UDPServer需要ILogger<UDPServer>,你只需要在容器里注册过ILogger,容器就会自动创建并注入这个依赖,你根本不用手动去new Logger。
  • 统一生命周期管理:通过AddTransient(每次获取都new一个新的)、AddScoped(每个作用域一个实例)、AddSingleton(全局单例)这几个方法,你可以轻松控制实例的生命周期,容器会帮你处理实例的创建、复用和销毁,不用自己写一堆冗余的管理逻辑。
  • 测试起来巨方便:做单元测试的时候,你可以直接在ServiceCollection里注册IUdpListener的Mock实现(比如用Moq框架创建的Mock<IUdpListener>),然后通过容器获取实例,完全不用修改UdpFactory的代码,测试的隔离性和灵活性直接拉满。

回到你的代码场景

现在你的UDPServer和UDPServerClnt可能没有额外依赖,所以直接new看起来问题不大,但这是典型的“短视”写法——业务一复杂,上面说的那些局限就会逐个暴露出来。而注释里的DI容器方式,是在为未来的复杂度提前铺路,让代码更健壮、更易维护。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 12:35:30