前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >.NET Core开发实战(第5课:依赖注入:良好架构的起点)--学习笔记(中)

.NET Core开发实战(第5课:依赖注入:良好架构的起点)--学习笔记(中)

作者头像
郑子铭
发布2021-01-13 15:20:30
8500
发布2021-01-13 15:20:30
举报

05 | 依赖注入:良好架构的起点

除了使用泛型的方式注册服务之外,还有其他的方式

添加一个 OrderService

代码语言:javascript
复制
public interface IOrderService
{

}

public class OrderService : IOrderService
{

}


public class OrderServiceEx : IOrderService
{

}

在 Startup 中注册服务

代码语言:javascript
复制
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 OrderService());  //直接注入实例

    //// 通过工厂模式
    //services.AddSingleton<IOrderService>(serviceProvider =>
    //{
    //    return new OrderServiceEx();
    //});

    //services.AddScoped<IOrderService>(serviceProvider =>
    //{
    //    // 可以使用 IServiceProvider 入参,也就意味着可以从容器里面获取多个对象,进行组装,得到最终的实现实例
    //    // 也就是可以把工厂类设计的比较复杂,比如说实现类依赖了容器里面的另外一个类,或者用另一个类来包装原有的实现
    //    //serviceProvider.GetService<>()

    //    return new OrderServiceEx();
    //});

    #endregion

    #region 尝试注册(如果服务已经注册过,则不再注册)

    services.TryAddSingleton<IOrderService, OrderServiceEx>();

    #endregion

    services.AddControllers();
}

在服务端 WeatherForecastController 定义另外一个接口

代码语言:javascript
复制
// 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 的这一行代码

代码语言:javascript
复制
"launchUrl": "weatherforecast/getservicelist",

启动程序,输出如下:

代码语言:javascript
复制
获取到服务实例:DependencyInjectionDemo.Services.OrderService:25560520

只有一个实例,说明 TryAddSingleton 没有生效

接着,注册两个服务

代码语言:javascript
复制
services.AddSingleton<IOrderService>(new OrderService());
services.AddSingleton<IOrderService, OrderServiceEx>();

启动程序,输出如下:

代码语言:javascript
复制
获取到服务实例:DependencyInjectionDemo.Services.OrderService:16991442
获取到服务实例:DependencyInjectionDemo.Services.OrderServiceEx:25560520

结果获取到了两个实例

接下来,了解一下 TryAddEnumerable 与 TryAddSingleton 的区别

代码语言:javascript
复制
#region 尝试注册(如果服务已经注册过,则不再注册)

services.TryAddSingleton<IOrderService, OrderServiceEx>();// 接口类型重复,则不注册

services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderService>());// 相同类型的接口,实现类相同,则不注册

#endregion

注册服务

代码语言:javascript
复制
services.AddSingleton<IOrderService>(new OrderService());
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderService>());

启动程序,输出如下:

代码语言:javascript
复制
获取到服务实例:DependencyInjectionDemo.Services.OrderService:53046438

因为已经注册过 OrderService,所以第二句代码不生效

以不同的实现注册服务

代码语言:javascript
复制
services.AddSingleton<IOrderService>(new OrderService());
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());

启动程序,输出如下:

代码语言:javascript
复制
获取到服务实例:DependencyInjectionDemo.Services.OrderService:24219861
获取到服务实例:DependencyInjectionDemo.Services.OrderServiceEx:38855053

这样就可以获取到两个服务实例

刷新浏览器,再执行一遍

代码语言:javascript
复制
获取到服务实例:DependencyInjectionDemo.Services.OrderService:24219861
获取到服务实例:DependencyInjectionDemo.Services.OrderServiceEx:38855053
获取到服务实例:DependencyInjectionDemo.Services.OrderService:24219861
获取到服务实例:DependencyInjectionDemo.Services.OrderServiceEx:38855053

因为注册的是单例,所以两次请求获取到的实例都是相同的

这样做的好处是:一方面避免一个服务重复注册,也可以控制一个服务需要注册不同的实现

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 05 | 依赖注入:良好架构的起点
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档