/* 二.注册容器中的服务信息注册实例 —— 服务类型实现类型生命周期 */ containerBuilder.AddSingleton产品(); containerBuilder.AddTransient零件接口, 零件A(); // 三种注册服务 // 1.AddSingleton(单例)只创建一个单例 // 2.AddTransient(瞬时)每次获取都创建一个新对象每次调用都是一个新的对象 // 3.AddScoped(作用域)多用于Web服务(同一个会话是同一个服务)WPF中很少使用 // 1)单例 // 服务对象 实现对象 containerBuilder.AddSingleton产品(); // 2)瞬时 // 1AddTransient服务类型() 等价于 AddTransient服务类型, 实现类型()但是服务类型 实现类型 // 2AddTransient服务类型, 实现类型() 服务类型通常为接口或者基类 containerBuilder.AddTransient零件A(); containerBuilder.AddTransient零件接口, 零件A(); // 3)作用域(不会Web我就偷懒不讲了哈) // AddScoped接口或父类, 实现类() // 尝试注册 - 用法和上面一样效果 - 如果没注册就注册注册了就通过 // services.AddSingleton(); // services.AddScoped(); // services.AddTransient();2.2 三种常用注册方式这里只讲述三种最常见的注册方式类型注册实例注册和工厂注册注册方式示例容器负责创建常用程度类型注册AddXXX服务类型()服务类型 实现类型✅⭐⭐⭐⭐⭐AddXXX服务类型, 实现类型()✅⭐⭐⭐⭐实例注册AddXXX(obj)❌⭐⭐⭐工厂注册AddXXX(sp ...)部分负责⭐⭐0三种注册方式详细总结对比项类型注册实例注册工厂注册典型语法AddXXXT()AddXXXTService, TImplementation()AddXXX(obj)AddXXX(sp ...)注册内容类型信息已存在的对象实例对象创建方法Lambda对象何时创建获取服务时由容器创建注册前已创建获取服务时执行工厂函数创建谁决定如何创建对象容器屏幕前苦逼的你屏幕前苦逼的你容器是否负责创建✅❌部分负责容器是否管理生命周期✅✅✅是否支持依赖注入✅❌对象已创建✅是否可以获取容器中的其它服务自动注入❌✅通过sp.GetRequiredService()适用场景日常开发最常用已存在对象、第三方对象复杂初始化、特殊参数、条件创建常用程度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐WPF使用频率极高偶尔偶尔1类型注册容器负责创建类型注册有两种1.服务类型 注册类型// 服务类型 实现类型 AddXXX服务类型()这是WPF中最常用的注册方式services.AddSingleton产品(); services.AddTransient零件A(); // 等价于 services.AddSingleton产品, 产品(); services.AddTransient零件A, 零件A();2.服务类型 ≠ 注册类型AddXXX服务类型, 实现类型()有博客也叫这种方式为接口 / 基类注册// 接口注册 services.AddTransientILogger, FileLogger(); // 基类注册 services.AddSingleton零件Base, 零件A();2实例注册你先创建再交给容器实例注册主要针对于已经存在的对象直接使用存在的的实例❌容器不能使用已经存在的实例✔容器不会创建已经存在的实例实例已经创建完成因此容器不再负责创建# 类型注册使用容器注册产品 容器 ↓ new 产品() # # 实例注册将产品实例交给容器 new 产品() ↓ 容器代码示例SerialPort port new SerialPort(COM1, 115200); services.AddSingleton(port);3工厂注册你告诉容器以后怎么创建工厂注册实际上就是告诉容器不要使用默认的方法使用我提供给你的方法所以有其他博客说工厂注册的使用时机需要 复杂初始化需要配置参数根据条件创建对象时[!CAUTION]注册工厂时并不会立即执行 Lambda 表达式Lambda 只是被容器保存起来当获取服务调用服务时容器才会执行该 Lambda 来创建对象containerBuilder.AddSingleton零件A(); /// 这里是sp指IServiceProvider(当前容器) containerBuilder.AddSingleton产品(sp { // 现在这个大括号里面的内容就是你自定义的对象创建过程 var part sp.GetRequiredService零件A(); return new 产品(part); });获取产品 ↓ 执行工厂函数 ↓ 从容器获取零件A ↓ 创建并且返回产品3.构建容器BuildServiceProvider这个也不需要多讲但是有一个特别需要注意的地方[!IMPORTANT]BuildServiceProvider()会根据当前注册信息生成真正的 DI 容器换句话说前面的创建集合还并没有生成一个真正的DI容器在调用之前只有注册信息调用之后才能获取服务/* 三.生成容器 */ IServiceProvider container containerBuilder.BuildServiceProvider(); containerBuilder.MakeReadOnly(); // 将生成类集合声明为只读,后续再添加服务会进行报错 // containerBuilder.AddSingleton产品(); // 使用MakeReadOnly后报错4.获取服务GetService一般情况下我们会获取不带键的服务如下但是现在官方给了我们一种比较新的写法带键/* 四.服务调用(从容器获取对象) */ // 不带键 产品? product container.GetService产品(); 产品 product2 container.GetRequiredService产品();