.NET Core开发实战(第5课:依赖注入:良好架构的起点)--学习笔记(中)
05 | 依赖注入:良好架构的起点
除了使用泛型的方式注册服务之外,还有其他的方式
添加一个 OrderService
public interface IOrderService
{
}
public class OrderService1 : IOrderService
{
}
public class OrderService2 : IOrderService
{
}
在 Startup 中注册服务
public void ConfigureServices(IServiceCollection services)
{
#region 注册服务不同生命周期的服务
// 将单例的服务注册为单例的模式
services.AddSingleton<IMySingletonService, MySingletonService>();
// Scoped 的服务注册为 Scoped 的生命周期
services.AddScoped<IMyScopedService, MyScopedService>();
// 瞬时的服务注册为瞬时的生命周期
services.AddTransient<IMyTransientService, MyTransientService>();
#endregion
#region 花式注册
services.AddSingleton<IOrderService>(new OrderService1()); //直接注入实例
#endregion
#region 尝试注册(如果服务已经注册过,则不再注册)
services.TryAddSingleton<IOrderService, OrderService2>();
#endregion
services.AddControllers();
}
在服务端 WeatherForecastController 定义另外一个接口
// IEnumerable<IOrderService>:获取曾经注册过的所有 IOrderService
public int GetServiceList([FromServices]IEnumerable<IOrderService> services)
{
foreach (var item in services)
{
Console.WriteLine($"获取到服务实例:{item.ToString()}:{item.GetHashCode()}");
}
return 1;
}
调整一下程序的启动页面,Properties 下的 launchSetting.json 的这一行代码
"launchUrl": "weatherforecast/getservicelist",
修改路由
[Route("[controller]/[action]")]
public class WeatherForecastController : ControllerBase
启动程序,输出如下:
获取到服务实例:DependencyInjectionDemo.Services.OrderService1:25560520
只有一个实例,说明 TryAddSingleton 没有生效
接着,注册两个服务
services.AddSingleton<IOrderService>(new OrderService1());
services.AddSingleton<IOrderService, OrderService2>();
启动程序,输出如下:
获取到服务实例:DependencyInjectionDemo.Services.OrderService1:16991442
获取到服务实例:DependencyInjectionDemo.Services.OrderService2:25560520
结果获取到了两个实例
接下来,了解一下 TryAddEnumerable 与 TryAddSingleton 的区别
#region 尝试注册(如果服务已经注册过,则不再注册)
services.TryAddSingleton<IOrderService, OrderService2>();// 接口类型重复,则不注册
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderService1>());// 相同类型的接口,实现类相同,则不注册
#endregion
注册服务
services.AddSingleton<IOrderService>(new OrderService1());
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderService1>());
启动程序,输出如下:
获取到服务实例:DependencyInjectionDemo.Services.OrderService1:53046438
因为已经注册过 OrderService,所以第二句代码不生效
以不同的实现注册服务
services.AddSingleton<IOrderService>(new OrderService1());
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderService2>());
启动程序,输出如下:
获取到服务实例:DependencyInjectionDemo.Services.OrderService1:24219861
获取到服务实例:DependencyInjectionDemo.Services.OrderService2:38855053
这样就可以获取到两个服务实例
刷新浏览器,再执行一遍
获取到服务实例:DependencyInjectionDemo.Services.OrderService1:24219861
获取到服务实例:DependencyInjectionDemo.Services.OrderService2:38855053
获取到服务实例:DependencyInjectionDemo.Services.OrderService1:24219861
获取到服务实例:DependencyInjectionDemo.Services.OrderService2:38855053
因为注册的是单例,所以两次请求获取到的实例都是相同的
这样做的好处是:一方面避免一个服务重复注册,也可以控制一个服务需要注册不同的实现
GitHub源码链接:
https://github.com/MingsonZheng/DotNetCoreDevelopmentActualCombat/tree/main/DependencyInjectionDemo
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。