山东建设监理协会官方网站网页打不开但是微信和qq都可以上
山东建设监理协会官方网站,网页打不开但是微信和qq都可以上,做网站 搞流量 赚广告费,wordpress主题UIGREAT一、服务注册的核心概念1. 什么是服务注册#xff1f;服务注册是.NET 依赖注入#xff08;DI#xff09;体系中的核心操作#xff0c;本质是将服务类型#xff08;接口 / 抽象类#xff09;与具体实现类型、生命周期绑定#xff0c;并存储到 DI 容器中 的过程。服务类型…一、服务注册的核心概念1. 什么是服务注册服务注册是.NET 依赖注入DI体系中的核心操作本质是将服务类型接口 / 抽象类与具体实现类型、生命周期绑定并存储到 DI 容器中的过程。服务类型对外暴露的抽象契约通常是接口 / 抽象类比如IUserService。实现类型服务类型的具体实现类比如UserService。DI 容器存储服务注册信息的 “容器”程序运行时可从中 “取出”解析服务实例。生命周期决定 DI 容器创建服务实例的规则是服务注册的核心属性。2. 服务的三种核心生命周期生命周期类型核心特点适用场景瞬时Transient每次解析都创建全新实例无状态、轻量级服务如工具类、数据验证器作用域Scoped同一个作用域内解析多次返回同一个实例不同作用域返回不同实例有状态的短期服务如数据库上下文 DbContext单例Singleton整个应用生命周期内无论解析多少次都返回同一个实例无状态、全局复用的服务如配置管理器、缓存服务3. 服务注册的核心价值解耦调用方只依赖抽象接口不依赖具体实现符合 “依赖倒置原则”可替换修改实现类时只需修改注册逻辑无需改动调用代码自动管理生命周期DI 容器自动创建、销毁实例无需手动new和释放简化测试可轻松替换为模拟Mock服务方便单元测试。二、服务注册的核心用法.NET 提供了IServiceCollection接口作为服务注册的入口核心注册方法如下注册方法用途示例AddTransientTService, TImplementation()注册瞬时服务services.AddTransientIUserService, UserService()AddScopedTService, TImplementation()注册作用域服务services.AddScopedIOrderService, OrderService()AddSingletonTService, TImplementation()注册单例服务services.AddSingletonICacheService, CacheService()AddSingletonTService(instance)注册已实例化的单例services.AddSingletonICacheService(new CacheService())AddTService()简写默认瞬时services.AddUserService()三、控制台案例步骤 1创建控制台项目环境准备打开 Visual Studio/VS Code创建.NET 8或更高版本控制台项目确保项目文件.csproj包含Microsoft.Extensions.DependencyInjection包默认已包含若缺失可通过 NuGet 安装Project SdkMicrosoft.NET.Sdk PropertyGroup OutputTypeExe/OutputType TargetFrameworknet8.0/TargetFramework ImplicitUsingsenable/ImplicitUsings Nullableenable/Nullable /PropertyGroup !-- 若缺失依赖添加以下包引用 -- ItemGroup PackageReference IncludeMicrosoft.Extensions.DependencyInjection Version8.0.0 / /ItemGroup /Project步骤 2定义服务接口和实现类先定义 3 个不同生命周期的服务using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; // 1. 定义服务接口抽象契约 /// summary /// 瞬时服务接口用户服务 /// /summary public interface IUserService { // 获取服务实例ID用于验证生命周期 Guid GetServiceInstanceId(); // 模拟业务方法获取用户名 string GetUserName(int userId); } /// summary /// 作用域服务接口订单服务 /// /summary public interface IOrderService { Guid GetServiceInstanceId(); // 模拟业务方法获取订单号 string GetOrderNo(int orderId); } /// summary /// 单例服务接口缓存服务 /// /summary public interface ICacheService { Guid GetServiceInstanceId(); // 模拟业务方法设置缓存 void SetCache(string key, string value); // 模拟业务方法获取缓存 string? GetCache(string key); } // 2. 实现服务类 /// summary /// 用户服务实现瞬时 /// /summary public class UserService : IUserService { // 每个实例唯一ID用于验证生命周期 private readonly Guid _instanceId; // 构造函数创建实例时生成唯一ID public UserService() { _instanceId Guid.NewGuid(); Console.WriteLine($【UserService】实例已创建ID{_instanceId}); } public Guid GetServiceInstanceId() _instanceId; public string GetUserName(int userId) { return userId switch { 1 张三, 2 李四, _ 未知用户 }; } } /// summary /// 订单服务实现作用域 /// /summary public class OrderService : IOrderService { private readonly Guid _instanceId; public OrderService() { _instanceId Guid.NewGuid(); Console.WriteLine($【OrderService】实例已创建ID{_instanceId}); } public Guid GetServiceInstanceId() _instanceId; public string GetOrderNo(int orderId) { return $ORDER_{orderId}_{DateTime.Now:yyyyMMdd}; } } /// summary /// 缓存服务实现单例 /// /summary public class CacheService : ICacheService { private readonly Guid _instanceId; // 模拟缓存存储 private readonly Dictionarystring, string _cacheDict new(); public CacheService() { _instanceId Guid.NewGuid(); Console.WriteLine($【CacheService】实例已创建ID{_instanceId}); } public Guid GetServiceInstanceId() _instanceId; public void SetCache(string key, string value) { _cacheDict[key] value; Console.WriteLine($【CacheService】缓存已设置{key} {value}); } public string? GetCache(string key) { _cacheDict.TryGetValue(key, out var value); return value; } }步骤 3服务注册与解析编写主程序完成服务注册、不同生命周期的解析验证/// summary /// 主程序 /// /summary class Program { static void Main(string[] args) { Console.WriteLine( .NET服务注册与依赖注入演示 ); Console.WriteLine(); // 步骤1创建服务集合ServiceCollection用于注册服务 // IServiceCollection是服务注册的容器本质是存储服务描述的列表 var services new ServiceCollection(); // 步骤2注册服务核心操作 Console.WriteLine(【第一步】开始注册服务...); // 1. 注册瞬时服务每次解析都创建新实例 services.AddTransientIUserService, UserService(); // 2. 注册作用域服务同一个作用域内实例唯一 services.AddScopedIOrderService, OrderService(); // 3. 注册单例服务整个应用生命周期内实例唯一 // 方式1通过类型注册推荐容器自动创建实例 services.AddSingletonICacheService, CacheService(); // 方式2直接注册已实例化的单例适用于需要手动初始化的场景 // var cacheInstance new CacheService(); // services.AddSingletonICacheService(cacheInstance); Console.WriteLine(【第一步】服务注册完成); Console.WriteLine(); // 步骤3构建服务提供器ServiceProvider用于解析服务 // ServiceProvider是DI容器的核心负责根据注册信息创建/解析服务实例 using var serviceProvider services.BuildServiceProvider(); // 步骤4验证不同生命周期的服务特性 Console.WriteLine(【第二步】验证瞬时服务Transient特性每次解析都是新实例); VerifyTransientService(serviceProvider); Console.WriteLine(); Console.WriteLine(【第三步】验证作用域服务Scoped特性同作用域内实例唯一不同作用域不同实例); VerifyScopedService(serviceProvider); Console.WriteLine(); Console.WriteLine(【第四步】验证单例服务Singleton特性全局唯一实例); VerifySingletonService(serviceProvider); Console.WriteLine(); Console.WriteLine(【第五步】服务依赖注入演示服务嵌套调用); VerifyServiceDependency(serviceProvider); Console.WriteLine(); Console.WriteLine( 演示结束 ); Console.ReadLine(); } #region 辅助方法验证不同生命周期的服务 /// summary /// 验证瞬时服务每次解析都是新实例 /// /summary private static void VerifyTransientService(IServiceProvider serviceProvider) { // 第一次解析瞬时服务 var userService1 serviceProvider.GetRequiredServiceIUserService(); Console.WriteLine($第一次解析IUserService实例ID{userService1.GetServiceInstanceId()}); Console.WriteLine($业务方法调用用户1的名称 {userService1.GetUserName(1)}); // 第二次解析瞬时服务应该是新实例 var userService2 serviceProvider.GetRequiredServiceIUserService(); Console.WriteLine($第二次解析IUserService实例ID{userService2.GetServiceInstanceId()}); Console.WriteLine($业务方法调用用户2的名称 {userService2.GetUserName(2)}); // 验证两次解析的实例ID是否不同瞬时服务特性 Console.WriteLine($瞬时服务验证结果两次实例是否相同 {userService1.GetServiceInstanceId() userService2.GetServiceInstanceId()}); } /// summary /// 验证作用域服务同作用域内实例唯一不同作用域不同实例 /// /summary private static void VerifyScopedService(IServiceProvider serviceProvider) { // 作用域1创建第一个作用域 using (var scope1 serviceProvider.CreateScope()) { var scopeProvider1 scope1.ServiceProvider; // 作用域1内第一次解析 var orderService1_1 scopeProvider1.GetRequiredServiceIOrderService(); Console.WriteLine($作用域1 - 第一次解析IOrderService实例ID{orderService1_1.GetServiceInstanceId()}); Console.WriteLine($业务方法调用订单1的编号 {orderService1_1.GetOrderNo(1)}); // 作用域1内第二次解析应该是同一个实例 var orderService1_2 scopeProvider1.GetRequiredServiceIOrderService(); Console.WriteLine($作用域1 - 第二次解析IOrderService实例ID{orderService1_2.GetServiceInstanceId()}); Console.WriteLine($作用域1内验证两次实例是否相同 {orderService1_1.GetServiceInstanceId() orderService1_2.GetServiceInstanceId()}); } // 作用域2创建第二个作用域 using (var scope2 serviceProvider.CreateScope()) { var scopeProvider2 scope2.ServiceProvider; // 作用域2内解析应该是新实例 var orderService2 scopeProvider2.GetRequiredServiceIOrderService(); Console.WriteLine($作用域2 - 解析IOrderService实例ID{orderService2.GetServiceInstanceId()}); Console.WriteLine($业务方法调用订单2的编号 {orderService2.GetOrderNo(2)}); } } /// summary /// 验证单例服务全局唯一实例 /// /summary private static void VerifySingletonService(IServiceProvider serviceProvider) { // 第一次解析单例服务 var cacheService1 serviceProvider.GetRequiredServiceICacheService(); cacheService1.SetCache(user_1, 张三); Console.WriteLine($第一次解析ICacheService实例ID{cacheService1.GetServiceInstanceId()}); Console.WriteLine($缓存读取user_1 {cacheService1.GetCache(user_1)}); // 第二次解析单例服务应该是同一个实例 var cacheService2 serviceProvider.GetRequiredServiceICacheService(); Console.WriteLine($第二次解析ICacheService实例ID{cacheService2.GetServiceInstanceId()}); Console.WriteLine($缓存读取复用第一次设置的值user_1 {cacheService2.GetCache(user_1)}); // 在作用域内解析单例仍然是同一个实例 using (var scope serviceProvider.CreateScope()) { var cacheService3 scope.ServiceProvider.GetRequiredServiceICacheService(); Console.WriteLine($作用域内解析ICacheService实例ID{cacheService3.GetServiceInstanceId()}); Console.WriteLine($缓存读取user_1 {cacheService3.GetCache(user_1)}); } // 验证所有解析的实例ID是否相同 var isSame cacheService1.GetServiceInstanceId() cacheService2.GetServiceInstanceId(); Console.WriteLine($单例服务验证结果所有实例是否相同 {isSame}); } /// summary /// 验证服务依赖注入一个服务依赖另一个服务 /// /summary private static void VerifyServiceDependency(IServiceProvider serviceProvider) { // 先注册一个依赖其他服务的新服务 // 定义一个业务服务依赖IUserService和ICacheService services.AddTransientIBusinessService, BusinessService(); // 注意这里需要先把services变量改为类级别的静态变量或重新注册 // 重新构建服务提供器因为新增了注册 using var newServiceProvider services.BuildServiceProvider(); var businessService newServiceProvider.GetRequiredServiceIBusinessService(); businessService.DoBusiness(1); } #endregion } // 补充服务依赖的示例 /// summary /// 业务服务接口依赖其他服务 /// /summary public interface IBusinessService { void DoBusiness(int userId); } /// summary /// 业务服务实现构造函数注入IUserService和ICacheService /// /summary public class BusinessService : IBusinessService { // 依赖的服务通过构造函数注入DI容器自动解析 private readonly IUserService _userService; private readonly ICacheService _cacheService; // 构造函数注入是.NET DI的默认方式推荐 public BusinessService(IUserService userService, ICacheService cacheService) { _userService userService; _cacheService cacheService; Console.WriteLine($【BusinessService】实例已创建依赖的IUserService实例ID{userService.GetServiceInstanceId()}); Console.WriteLine($【BusinessService】实例已创建依赖的ICacheService实例ID{cacheService.GetServiceInstanceId()}); } public void DoBusiness(int userId) { var userName _userService.GetUserName(userId); _cacheService.SetCache($business_user_{userId}, userName); Console.WriteLine($【BusinessService】业务处理完成用户{userId}的名称是{userName}已缓存); } }步骤 4代码关键说明服务注册核心ServiceCollection是 “注册清单”通过AddXxx方法将服务类型与实现类型、生命周期绑定BuildServiceProvider()将注册清单转换为可解析服务的ServiceProviderDI 容器。服务解析方法GetRequiredServiceT()强制解析服务若服务未注册则抛出异常推荐GetServiceT()解析服务若未注册则返回nullCreateScope()创建作用域作用域内解析的 Scoped 服务实例唯一。依赖注入方式示例中BusinessService通过构造函数注入依赖的IUserService和ICacheService这是.NET DI 的默认且推荐的方式DI 容器会自动解析依赖链解析IBusinessService时先解析其构造函数中的IUserService和ICacheService再创建BusinessService实例。步骤 5运行结果分析运行程序后会看到以下关键输出瞬时服务两次解析的IUserService实例 ID 完全不同作用域服务同一个作用域内两次解析的IOrderService实例 ID 相同不同作用域 ID 不同单例服务无论直接解析还是在作用域内解析ICacheService的实例 ID 始终相同且缓存数据可复用依赖注入BusinessService创建时DI 容器自动注入依赖的服务实例无需手动new。四、扩展知识点服务注册的其他方式泛型服务注册services.AddTransient(typeof(IGenericService), typeof(GenericService))工厂模式注册services.AddTransientIUserService(sp new UserService(自定义参数))服务生命周期注意事项禁止在 “短生命周期服务” 中注入 “长生命周期服务”如 Scoped 服务注入 Singleton 服务会导致 Scoped 服务被 “提升” 为 Singleton引发线程安全问题瞬时服务可注入任意生命周期的服务单例服务只能注入单例服务。控制台项目 vs Web 项目Web 项目中每个 HTTP 请求对应一个作用域Scoped因此 Scoped 服务默认在单个请求内唯一控制台项目需手动创建作用域CreateScope()否则解析 Scoped 服务会抛出异常。总结核心概念服务注册是将 “抽象服务类型 - 具体实现类型 - 生命周期” 绑定并存储到 DI 容器的过程目的是解耦和自动管理实例核心操作通过ServiceCollection的AddTransient/AddScoped/AddSingleton完成注册通过ServiceProvider解析服务生命周期关键瞬时每次新实例、作用域同作用域唯一、单例全局唯一需根据业务场景选择。