zoukankan      html  css  js  c++  java
  • 一、.Net Core 依赖注入详解及Autofac使用

    .NET中的依赖注入实际上帮助我们解耦了我们的代码,是控制反转和依赖反转原则的具体实现。

    .Net Core的依赖注入的好处:

    1. application 更稳定,容易维护和演化;

    2. 实现细节的变化,不需要到处更改,在声明的时候进行替换即可;

    3. 测试更容易,更好地mock依赖的service等。

    4. 高级的模块或者服务不应该依赖于具体的实现,而是抽象。

    服务的生命周期

    1. Singleton: 应用程序运行期间是唯一的。需要考虑线程安全性,效率高

    2. Scoped: 每个请求期间,实例唯一;需要考虑线程安全性,效率

    3. Transient: 每次需要的时候实例化,不需要考虑线程安全,效率相对较低

    关于服务的声明周期: 一个服务不应该依赖于比它生命周期短的服务。

    我们通过 AddTransient,AddSingleton, AddScoped  可以完成大多数的场景需要;

    serviceDescriptor 对象一般是隐含在直接调用的AddSingleton/AddTransient/AddScoped中的。

    复制代码
    var serviceDescriptor = new ServiceDescriptor.Singleton<IServiceA, ServiceA>();
    
    services.Add(serviceDescriptor);
    
    === 等价于
    
    
    services.AddSingleto<IServiceA, ServiceA>();
    复制代码

    ServiceCollection 复杂场景的使用

    1. 同一个接口的不同实现,TryAdd

    DI container 会按照注入顺序去resolve需要的接口实现,如下:

    复制代码
    services.AddSingleton<IWeatherForecaster, WeatherForecaster>();
    services.AddSingleton<IWeatherForecaster, AmazingWeatherForecaster>();
    -------
    
    public ServiceA(private IWeatherForecaster _weather) {
    }
    复制代码
    _weather 实例化出来的 class 是typeof(AmazingWeatherForecaste), 按照我们在 ConfigureServices 中声明的顺序,最后一个起作用;


    对ServiceCollection 的理解:serviceCollection是一个集合,里面包含了webhost加入的一些内置 ServiceDescriptors, 以及我们在configureservices 中声明的注入。
    因此,本质上,我们对于这个servicecollection里面的操作可以参照集合的操作。

    2. 取代接口的实现和移除接口的所有实现
    Replace: 取代servicetype 的第一个实现,示例如下。
    services.AddSingleton<IWeatherForecaster, WeatherForecaster>();
    services.Replace(ServiceDescriptor.Singleton<IWeatherForecaster, AmazingWeatherForecaster>());

    通过如上代码,我们在 service collection中只能找到  IWeatherForecaster 实现 只有 AmazingWeatherForecaster, 因为AmazingWeatherForecaster 取代了  WeatherForecaster。

     RemoveAll: 在service collection 中移除serviceType 的所有实现

    3. 注册接口的多个实现

    我们知道,在service collection中,是可以存在一个接口多个实现的注册信息的,那么我们有什么好的方法去注册一个接口的多个实现么? TryAddEnumerable

    复制代码
    services.TryAddEnumerable(new[]
                {
                    ServiceDescriptor.Singleton<ICourtBookingRule, ClubIsOpenRule>(),
                    ServiceDescriptor.Singleton<ICourtBookingRule, MaxBookingLengthRule>(),
                    ServiceDescriptor.Singleton<ICourtBookingRule, MaxPeakTimeBookingLengthRule>(),
                });
    
    === 等价于
               services.TryAddEnumerable(ServiceDescriptor.Singleton<ICourtBookingRule, ClubIsOpenRule>());
                services.TryAddEnumerable(ServiceDescriptor.Singleton<ICourtBookingRule, MaxBookingLengthRule>());
                
    复制代码

    4. 工厂模式

    工厂模式允许我们在创建service 时候更加随心所欲, 拥有自己的掌控度。

    复制代码
    services.TryAddSingleton<EmailNotificationService>();
    services.TryAddSingleton<SmsNotificationService>();
    
     services.AddSingleton<INotificationService>(sp =>
            new CompositeNotificationService(
                new INotificationService[]
                 {
                        sp.GetRequiredService<EmailNotificationService>(),
                        sp.GetRequiredService<SmsNotificationService>()
                  })); 
    复制代码

    例子中的使用场景是: 我们通过 CompositeNotificationService 去组合各种的 INotificationService, 因此使方不需要关心如何发notification 或者需要发送多少类型的notification。

    ------------------------

    鉴于后续内容还有不少,关于在DI 使用时的注意事项,及引入第三方的依赖注入框架,剩下内容会更新在下一篇。欢迎大家讨论交流,指出不足,谢谢!

  • 相关阅读:
    PHP流程控制之do...while循环的区别
    php流程控制 之循环语句的使用
    PHP流程控制之分支结构switch语句的使用
    PHP流程控制之if语句多种嵌套
    PHP流程控制之嵌套if...else...elseif结构
    PHP基础语法之 三元运算符和其它运算符
    PHP基础语法之 位运算
    php常量和变量之变量引用
    php数据类型之自动转换和强制转换
    php数据类型之查看和判断数据类型
  • 原文地址:https://www.cnblogs.com/wl-blog/p/15003045.html
Copyright © 2011-2022 走看看