• C# .NET 5.0 依赖注入


    参考:

    https://www.cnblogs.com/zoro-zero/p/13490459.html

    https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1

    DI:是一种软件设计模式,Asp.net core支持该模式。这是一种在类及其依赖关系之间实现控制反转 (IoC) 的技术。

    依赖项:指另一个对象所依赖的对象。

    常见的DI框架:Autofac、Unity......

    依赖关系注入概述——  谁依赖谁,将谁注入谁

    依赖注入是指在创建一个对象时,自动地创建它所依赖的对象,并注入。

    依赖注入的方式:1.构造方法注入;  2.Set方法注入;  3.方法参数注入

    1.构造方法注入:

    优点:

    • 在构造方法中体现出对其他类的依赖,直接就可以看出这个类所需要的依赖那些类才能工作。
    • 脱离了IOC框架,这个类仍然可以工作。
    • 一旦对象初始化成功了,这个对象的状态肯定是正确的。

    缺点:

    • 构造函数会有很多参数(Bad smell)。
    • 有些类是需要默认构造函数的,比如MVC框架的Controller类,一旦使用构造函数注入,就无法使用默认构造函数。
    • 这个类里面的有些方法并不需要用到这些依赖(Bad smell)。

    2.Set方法注入

    优点:
    • 在对象的整个生命周期内,可以随时动态的改变依赖。
    • 非常灵活。
    缺点:
    • 对象在创建后,被设置依赖对象之前这段时间状态是不对的。
    • 不直观,无法清晰地表示哪些属性是必须的。

    3.方法参数注入--即以入参的方法,将对象赋值给方法内的对象

    方法参数注入的意思是在创建对象后,通过自动调用某个方法来注入依赖。类似如下代码:

    public class MovieRecommender {
     
     private MovieCatalog movieCatalog;
     public class MovieRecommender {
     
      private MovieCatalog movieCatalog;
     
      private CustomerPreferenceDao customerPreferenceDao;
     
      @Autowired
      public void prepare(MovieCatalog movieCatalog,
                          CustomerPreferenceDao customerPreferenceDao) {
          this.movieCatalog = movieCatalog;
          this.customerPreferenceDao = customerPreferenceDao;
      }
     
      // ...
    }
      private CustomerPreferenceDao customerPreferenceDao;
     
      public void prepare(MovieCatalog movieCatalog,
                          CustomerPreferenceDao customerPreferenceDao) {
          this.movieCatalog = movieCatalog;
          this.customerPreferenceDao = customerPreferenceDao;
      }
     
      // ...
    }
    
    一般只有一个方法依赖到注入的对象时用到
    如果有多个方法依赖到注入的对象,还是使用构造方法注入方式比较合适
    优点:
    • 比较灵活。
    缺点:
    • 新加入依赖时会破坏原有的方法签名,如果这个方法已经被其他很多模块用到就很麻烦。
    • 与构造方法注入一样,会有很多参数。

    依赖注入使用注意事项:

    1.使用接口或基类将依赖关系实现抽象化

    2.在服务容器中注册依赖关系。 ASP.NET Core 提供了一个内置的服务容器 IServiceProvider。 服务通常已在应用的 Startup.ConfigureServices 方法中注册。

    3.将服务注入到使用它的类的构造函数中。 框架负责创建依赖关系的实例,并在不再需要时将其释放。

    如下所示:

    using System;
    
    namespace Models
    {
        public interface IMyDependency
        {
            void WriteMessage(string message);
        }
    }
    
    using System;
    
    namespace Models
    {
        /// <summary>
        /// 示例应用使用具体类型 MyDependency 注册 IMyDependency 服务
        /// </summary>
        public class MyDependency : IMyDependency
        {
            /// <summary>
            /// 传参注入
            /// </summary>
            /// <param name="message">依赖项</param>
            public void WriteMessage(string message)
            {
                Console.WriteLine($"MyDependency.WriteMessage Message: {message}");
            }
        }
    }
    注:以上示例应用使用具体类型 MyDependency 注册 IMyDependency 服务;
    AddScoped 方法使用范围内生存期(单个请求的生存期)注册服务
    public void ConfigureServices(IServiceCollection services)
    { 
      services.AddScoped<IMyDependency, MyDependency>(); services.AddRazorPages(); 
    }
    在示例应用中,请求 IMyDependency 服务并用于调用 WriteMessage 方法:
    namespace Models.Model.Demo1
    {
        public class OneModel
        {
            private readonly IMyDependency _myDependency;
            public OneModel(IMyDependency myDependency)
            {
                _myDependency = myDependency;
            }
    
            public void OnGet()
            {
                _myDependency.WriteMessage("OneModel.OnGet");
            }
        }
    }
    

    通过使用 DI 模式,表示控制器:

    • 不使用具体类型 MyDependency,仅使用它实现的 IMyDependency 接口。 这样可以轻松地更改控制器使用的实现,而无需修改控制器。
    • 不创建 MyDependency 的实例,这由 DI 容器创建。

    可以通过使用内置日志记录 API 来改善 IMyDependency 接口的实现:using Microsoft.Extensions.Logging;

    namespace Models.Model.Demo1
    {
        public class MyDependency2 : IMyDependency
        {
            private readonly ILogger<MyDependency2> _logger;
            /// <summary>
            /// 构造注入
            /// </summary>
            /// <param name="logger">依赖项</param>
            public MyDependency2(ILogger<MyDependency2> logger)
            {
                _logger = logger;
            }
            /// <summary>
            /// 传参注入
            /// </summary>
            /// <param name="message">依赖项</param>
            public void WriteMessage(string message)
            {
                _logger.LogInformation($"MyDependency2.WriteMessage Message: {message}");
            }
        }
    }

    更新的 ConfigureServices 方法注册新的 IMyDependency 实现:
    public void ConfigureServices(IServiceCollection services) 
    { 
      services.AddScoped<IMyDependency, MyDependency2>(); 
    }
    MyDependency2 依赖于 ILogger<TCategoryName>,并在构造函数中对其进行请求。 ILogger<TCategoryName> 是框架提供的服务
    必须被解析的依赖关系的集合通常被称为“依赖关系树”、“依赖关系图”或“对象图”

    容器通过利用(泛型)开放类型解析 ILogger<TCategoryName>,而无需注册每个(泛型)构造类型

    在依赖项注入术语中,服务:

    • 通常是向其他对象提供服务的对象,如 IMyDependency 服务。
    • 与 Web 服务无关,尽管服务可能使用 Web 服务。

      

      

    博客内容主要用于日常学习记录,内容比较随意,如有问题,还需谅解!!!
  • 相关阅读:
    范例-项目-.NET-PetShop-4.0-架构设计:目录、PetShop概述
    汉语-词语:立志
    汉语-汉字:被
    汉语-成语:被褐怀珠
    汉语-成语:被褐怀玉
    汉语-成语:被褐藏辉
    汉语-词语:处世
    使用exp&imp工具进行数据库备份及恢复
    oracle创建表空间-用户-角色-授权
    linux下单独安装oracle12.1客户端
  • 原文地址:https://www.cnblogs.com/YYkun/p/15594585.html
Copyright © 2020-2023  润新知