zoukankan      html  css  js  c++  java
  • asp.net core 系列 3 依赖注入服务

    一. 依赖注入概述

      在软件设计的通用原则中,SOLID是非常流行的缩略语,它由5个设计原则的首字母构成:单一原则(S)、开放封闭原则(O)、里氏替换原则(L)、接口分离原则(I)、依赖反转原则(D)。本篇介绍依赖反转原则以及在ASP.NET Core中的实现。

      直接依赖是指:当一个类需要另一个类协作来完成工作的时候就产生了依赖。举例比如:模块 A 调用模块 B 中的函数,而模块 B 又调用模块 C 中的函数,则编译时 A 取决于 B,而 B 又取决于 C。这是有严重的依赖关系,不属于松散耦合。

      依赖反转是指:高层模块不应该依赖低层模块,二者都应该依赖于抽象,是对接口而不是实现编程。当一个类(Class)需要被外部依赖,就需要把它抽象成一个接口(interface),如何把这个接口变成具体可调用的实例,就是由依赖注入来完成。依赖反转是生成松散耦合应用程序的关键一环。当应用依赖反转原则后,A 可以调用 B 实现的抽象上的方法,让 A 可以在运行时调用 B,而 B 又在编译时依赖于 A 控制的接口。 运行时程序执行的流程保持不变,但接口引入意味着可以轻松插入这些接口的不同实现

      假设一个方法从流读取字节,并把它们写入某个缓冲:
    //直接依赖 这里的伪代码依赖于两个低层模块,读取器和写入器。

    void Copy()
    {
        Byte byte1;
        Reader reader = new Reader();
        Writer writer = new Writer();
        while (byte1 = reader.ReadFromStream())
            writer.WriteTobuffer(byte1);
    }
    //依赖反转 这里的伪代码依赖于两个抽象类,读取器和写入器。
    
    
    void Copy(IReader reader, IWriter writer)
        {
            Byte byte1;
            while (byte1 = reader.ReadFromStream())
                writer.WriteTobuffer(byte1)
        }
      上面接口的读取器和写入器的实例谁来提供呢?需要使用依赖注入模式。实现依赖注入需要使用IoC 容器,目前有Unity和MEF 2 二种IoC 容器工具来实现。以及下面讲到ASP.NET Core自带的依赖注入实现。

    二. ASP.NET Core依赖注入

      ASP.NET Core 支持依赖关系注入的设计模式,是类及其依赖关系之间实现控制反转 (IoC)的技术。在ASP.NET Core中依赖注入解决的问题包括:

      (1) 使用接口抽象化依赖关系实现。

      (2) 注册服务容器中的依赖关系。ASP.NET Core内置的服务容器 IServiceProvider。 实现在Startup.ConfigureServices 方法中注册服务(服务一般是接口)。

      (3) 将服务注入到使用它的类的构造函数中。

      下面示例中,使用具体类型 MyDependency 注册 IMyDependency 服务, 注册将服务生存期的范围限定为单个请求的生存期。在MyDependency实现类中使用框架内部已注入好的ILogger来帮助打印日志输出。

    // 第一步 使用接口抽象化来实现依赖反转, 定义 IMyDependency 服务

        public interface IMyDependency
        {
            Task WriteMessage(string message);
        }
        // IMyDependency 服务的实现类
        public class MyDependency : IMyDependency
        {
            private readonly ILogger<MyDependency> _logger;
    
            public MyDependency(ILogger<MyDependency> logger)
            {
                _logger = logger;
            }
    
            public Task WriteMessage(string message)
            {
                _logger.LogInformation(
                    "MyDependency.WriteMessage called. Message: {MESSAGE}",
                    message);
                return Task.FromResult(0);
            }
    }
    // 第二步在 将IMyDependency服务注册到服务容器中。
        
    public void ConfigureServices(IServiceCollection services)
    {
        //....
        //每次请求时创建,贯穿整个请求
        services.AddScoped<IMyDependency, MyDependency>();
        //....      
     }
    // 第三步 将服务注入到使用它的类的构造函数中,在Index.cshtml.cs类中调用IMyDependency服务的WriteMessage方法
    
        public class IndexModel : PageModel
        {
            private readonly IMyDependency _myDependency;
    
            public IndexModel(IMyDependency myDependency)
            {
                this._myDependency = myDependency;
            }
    
            public void OnGet()
            {
                    _myDependency.WriteMessage("IndexModel.OnGetAsync created this message.");
                
            }
      }
      下面是输出WriteMessage方法的日志信息:

       参考文献:

        Microsoft.NET 企业级应用 架构设计

        官方文档:ASP.NET Core 依赖注入

    欢迎添加个人微信号:Like若所思。

    欢迎关注我的公众号,不仅为你推荐最新的博文,还有更多惊喜和资源在等着你!一起学习共同进步!

    您的资助是我最大的动力!
    金额随意,欢迎来赏!

  • 相关阅读:
    WPF DelegateCommand 出现Specified cast is not valid
    WPF DelegateCommand 出现Specified cast is not valid
    WPF DelegateCommand 出现Specified cast is not valid
    win10 sdk 是否向下兼容
    win10 sdk 是否向下兼容
    win10 sdk 是否向下兼容
    PHP extract() 函数
    PHP end() 函数
    PHP each() 函数
    PHP current() 函数
  • 原文地址:https://www.cnblogs.com/cool2feel/p/11508023.html
Copyright © 2011-2022 走看看