.NET_控制反转简述

什么是控制反转?

控制反转(Inversion of Control,IoC)是面向对象编程中的一种设计原则,主要用于减少代码之间的耦合度。其通过将程序中的对象创建、销毁和对象间的依赖关系的管理权从代码中转移到外部容器或框架,从而实现了控制权的反转。 

如何实现控制反转?

控制反转的主要实现方式:依赖注入(需通过服务定位获取依赖注入的根节点)

依赖注入具有传染性:注册完成服务后,通过服务定位器获取服务时,框架会创建服务实例,并一同创建服务在构造函数中赋值的服务(依赖项),称为依赖注入(此时"创建"动作由框架完成,不由调用者完成,所以属于"控制反转",也就是说依赖注入是控制反转的一种实现方式),且该服务所依赖的服务所依赖的服务......均会被创建并注入
换言之,创建创建一个服务时,该服务所依赖的服务(通过构造函数传参)也会被一同创建,称为依赖的传染性

示例

依赖:Microsoft.Extensions.DependencyInjection

服务的生命周期:

Transient 瞬时(获取服务时创建新对象)
Scoped 范围(获取服务时,scope内为同一对象)
Singleton 单例(字面意思)

常用函数:

GetService()返回服务/GetServices()返回所有服务(无则返回null), GetRequiredService()返回服务(无则抛异常) 
注:关于GetService()/GetRequiredService(),当存在数个符合条件的服务时, 返回最后注册的服务

补充说明:

以IEnumerable<T>形式依赖注入, 则获取所有符合条件的服务

internal class Program
{
    public static void Main(string[] args)
    {
        // 注册类服务
        ServiceCollection serviceCollection = new();
        serviceCollection.AddTransient<StartTest_IEnumerable>();
        serviceCollection.AddTransient<StartTest>();
        // 注册接口服务
        serviceCollection.AddTransient<IConfig, ConfigImpl1>();
        serviceCollection.AddTransient<IConfig, ConfigImpl2>();
        serviceCollection.AddTransient<IConfig, ConfigImpl3>();
        serviceCollection.AddTransient<IGetData, GetDataImpl>();
        serviceCollection.AddTransient<ITest, TestImpl>();
        using (var serverProvider = serviceCollection.BuildServiceProvider())
        {
            // GetService()返回服务/GetServices()返回所有服务(无则返回null), GetRequiredService()返回服务(无则抛异常) 
            // GetService()/GetRequiredService(): 当存在数个符合条件的服务时, 返回最后注册的服务
            // 以IEnumerable<T>形式依赖注入, 则获取所有符合条件的服务

            var startTest_IEnumerable = serverProvider.GetRequiredService<StartTest_IEnumerable>();
            startTest_IEnumerable.Start();

            //var startTest = serverProvider.GetRequiredService<StartTest>();
            //startTest.Start();

            //IEnumerable<IConfig> configs = serverProvider.GetServices<IConfig>();
            //foreach (var item in configs)
            //{
            //    item.Config();
            //}
        }
    }

    class StartTest_IEnumerable
    {
        private IEnumerable<IConfig> config;
        private IGetData getData;
        private ITest test;
        public StartTest_IEnumerable(IEnumerable<IConfig> config, IGetData getData, ITest test) // 所注册服务为接口, 故参数类型也为接口
        {
            this.config = config;
            this.getData = getData;
            this.test = test;
        }
        public void Start()
        {
            foreach (var item in config)
            {
                item.Config();
            }
            getData.GetData();
            test.Test();
        }
    }
    class StartTest
    {
        private IConfig config;
        private IGetData getData;
        private ITest test;
        public StartTest(IConfig config, IGetData getData, ITest test) // 所注册服务为接口, 故参数类型也为接口
        {
            this.config = config;
            this.getData = getData;
            this.test = test;
        }
        public void Start()
        {
            config.Config();
            getData.GetData();
            test.Test();
        }
    }
    interface IConfig
    {
        public void Config();
    }
    class ConfigImpl1 : IConfig
    {
        public void Config()
        {
            Console.WriteLine("Config1...");
        }
    }
    class ConfigImpl2 : IConfig
    {
        public void Config()
        {
            Console.WriteLine("Config2...");
        }
    }
    class ConfigImpl3 : IConfig
    {
        public void Config()
        {
            Console.WriteLine("Config3...");
        }
    }
    interface IGetData
    {
        public void GetData();
    }
    class GetDataImpl : IGetData
    {
        public void GetData()
        {
            Console.WriteLine("GetData...");
        }
    }
    interface ITest
    {
        public void Test();
    }
    class TestImpl : ITest
    {
        public void Test()
        {
            Console.WriteLine("Test...");
        }
    }
}

相关推荐

  1. .NET_控制简述

    2024-05-11 17:02:11       38 阅读
  2. 简单的解释依赖注入和控制

    2024-05-11 17:02:11       49 阅读
  3. Spring中控制究竟的什么

    2024-05-11 17:02:11       26 阅读
  4. Go中的控制 IoC

    2024-05-11 17:02:11       45 阅读
  5. Spring控制(IOC)是什么

    2024-05-11 17:02:11       27 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-11 17:02:11       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-11 17:02:11       106 阅读
  3. 在Django里面运行非项目文件

    2024-05-11 17:02:11       87 阅读
  4. Python语言-面向对象

    2024-05-11 17:02:11       96 阅读

热门阅读

  1. No signature found in package of version 2 or newer for package

    2024-05-11 17:02:11       26 阅读
  2. go-Expect-实验

    2024-05-11 17:02:11       35 阅读
  3. Linux 第二十六章

    2024-05-11 17:02:11       33 阅读
  4. vue3-seamless-scroll实现循环滚动

    2024-05-11 17:02:11       27 阅读
  5. 以太网网络变压器型号

    2024-05-11 17:02:11       29 阅读
  6. git 更换远程仓库地址三种方法总结

    2024-05-11 17:02:11       28 阅读
  7. 【笔记】Android MVNO APN 字段配置方法

    2024-05-11 17:02:11       27 阅读
  8. react18【系列实用教程】useState (2024最新版)

    2024-05-11 17:02:11       38 阅读
  9. impdp恢复表后发现比原表多了100多行

    2024-05-11 17:02:11       32 阅读
  10. C++ 多线程笔记1 线程的创建

    2024-05-11 17:02:11       30 阅读
  11. 【Python快速上手(十九)】

    2024-05-11 17:02:11       30 阅读
  12. 【go从入门到精通】精通并发编程-协程goroutine

    2024-05-11 17:02:11       28 阅读