首页 > 其他分享 >从依赖倒置原则到IOC控制反转实现

从依赖倒置原则到IOC控制反转实现

时间:2024-04-24 09:22:05浏览次数:22  
标签:容器 IoC 依赖 反转 void TService 倒置 IOC public

从依赖倒置原则(Dependency Inversion Principle, DIP)到控制反转(Inversion of Control, IoC)再到依赖注入(Dependency Injection, DI)的演进过程,我们可以理解为一种逐步抽象和解耦的设计思想。这种思想在C#等面向对象的编程语言中得到了广泛的应用。

首先,让我们回顾一下依赖倒置原则。这个原则建议我们:

  • 高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
  • 抽象不应该依赖于细节,细节应该依赖于抽象。

这个原则鼓励我们设计代码时,让高层模块与底层模块之间的依赖通过抽象(接口或基类)来进行,从而减少了模块间的耦合度。

接下来,控制反转是一种设计模式,它通过将原本由代码直接控制的对象的调用权交给第三方(如一个容器)来控制,来降低代码间的耦合度。在C#中,IoC容器是实现控制反转的一个工具。

DI是IoC的一种实现方式,它将依赖关系通过构造函数、属性或方法注入到对象中。这种方式进一步降低了代码间的耦合度,使得对象在被创建时就能获得它所需要的依赖。

现在,我们来实现一个简单的IoC容器,并通过递归完成构造函数注入。以下是一个简单的示例:

public interface IService  
{  
    void DoWork();  
}  
  
public class ConcreteService : IService  
{  
    private readonly IDependency _dependency;  
  
    public ConcreteService(IDependency dependency)  
    {  
        _dependency = dependency;  
    }  
  
    public void DoWork()  
    {  
        _dependency.DoSomething();  
    }  
}  
  
public interface IDependency  
{  
    void DoSomething();  
}  
  
public class ConcreteDependency : IDependency  
{  
    public void DoSomething()  
    {  
        Console.WriteLine("Dependency is doing something...");  
    }  
}  
  
public class SimpleIoCContainer  
{  
    private readonly Dictionary<Type, Func<object>> _registrations = new Dictionary<Type, Func<object>>();  
  
    public void Register<TService, TImplementation>() where TImplementation : TService  
    {  
        _registrations.Add(typeof(TService), () => Activator.CreateInstance(typeof(TImplementation)));  
    }  
  
    public TService Resolve<TService>()  
    {  
        if (!_registrations.ContainsKey(typeof(TService)))  
        {  
            throw new InvalidOperationException($"No registration found for {typeof(TService).FullName}");  
        }  
  
        var factory = _registrations[typeof(TService)];  
        return (TService)factory();  
    }  
  
    public object Resolve(Type serviceType)  
    {  
        if (!_registrations.ContainsKey(serviceType))  
        {  
            throw new InvalidOperationException($"No registration found for {serviceType.FullName}");  
        }  
  
        var factory = _registrations[serviceType];  
        return factory();  
    }  
}  
  
public class Program  
{  
    public static void Main()  
    {  
        var container = new SimpleIoCContainer();  
        container.Register<IService, ConcreteService>();  
        container.Register<IDependency, ConcreteDependency>();  
  
        IService service = container.Resolve<IService>();  
        service.DoWork();  
    }  
}

在这个示例中,我们定义了一个简单的IoC容器SimpleIoCContainer,它使用了一个字典来存储服务类型到工厂方法的映射。Register方法用于注册服务,而Resolve方法用于解析服务。在这个例子中,ConcreteService依赖于IDependency,IoC容器负责在创建ConcreteService实例时注入ConcreteDependency实例。

应用场景

IoC容器和依赖注入在许多场景下都非常有用,包括但不限于:

  1. 单元测试:通过IoC容器,可以轻松地替换掉生产环境中的依赖,换成用于测试的桩(Stubs)或模拟对象(Mocks),从而方便地进行单元测试。

  2. 插件架构:在需要动态加载插件的系统中,IoC容器可以用来管理插件的生命周期和依赖关系,使得插件的加载和解耦变得更加容易。

  3. 微服务:在微服务架构中,每个微服务都可以使用IoC容器来管理其内部的依赖关系,从而确保服务之间的松耦合和易于维护。

  4. 复杂的应用程序:对于大型复杂的应用程序,IoC容器可以帮助开发人员更好地组织和管理代码,降低模块间的耦合度,提高代码的可维护性和可扩展性。

  5. 跨平台开发:在需要支持多个平台或框架的应用程序中,IoC容器可以提供一个统一的依赖注入机制,使得代码更加灵活和可移植。

标签:容器,IoC,依赖,反转,void,TService,倒置,IOC,public
From: https://www.cnblogs.com/forges/p/18154350

相关文章

  • 151. 反转字符串中的单词
    题目链接:151.反转字符串中的单词这题主要是熟悉java一些库的调用,先放代码:classSolution{publicStringreverseWords(Strings){s=s.trim();//去除两边多余空格List<String>list=Arrays.asList(s.split("\\s+"));//将字符串按空格切割Coll......
  • Python中列表和字符串的反转
    一、Python现成的反转功能:在Python中有专门进行列表反转的函数--reverse()l=[13,30,42,85,9,45]l.reverse()#[45,9,85,42,30,13]还可以使用切片操作进行列表反转l=[13,30,42,85,9,45]print(l[::-1])#[45,9,85,42,30,13]关于字符串的反转,并没......
  • Spring 源码阅读(二)IoC 容器初始化以及 BeanFactory 创建和 BeanDefinition 加载过程
    相关代码提交记录:https://github.com/linweiwang/spring-framework-5.3.33IoC容器三种启动方式XMLJavaSE:ApplicationContextcontext=newClassPathXmlApplicationContext("beans.xml")ApplicationContextcontext=newFileSystemXmlApplicationContext("C:/beans......
  • 7.整数反转
    题目:给一个32位有号整数,要求将整数反转得到新整数,若原整数不在[-2^31,2^31-1]范围,则返回0。Python理论上可以存储无穷大的数,因此题目的32位即[-2^31,2^31-1]只需Python作出范围的判断不用更换类型。反转的思路:进行类型的转换——将数转换成字符串类型,问题等价于反转字符串,按......
  • 快速理解Laravel容器(IOC、DI、Provider、Contract)
    源码理解思维的提升分享一些个人见解。Laravel里面的某些概念,就像魔术一样,看起来很厉害,当知道魔术怎么变的,就会认为也不过如此。所以不必感觉Laravel里有些概念难以理解。应当抛除被框架约束思维的枷锁,用PHP设计的角度去思考,关注大概,而不是在在框架层面逐行磨叽。毕竟源码那么......
  • 【chatgpt】IoCreateDevice和IoCreateSymbolicLink是两个重要的函数
    在Windows设备驱动程序开发中,IoCreateDevice和IoCreateSymbolicLink是两个重要的函数,用于创建设备对象和符号链接,它们的作用如下:IoCreateDevice:作用:创建一个设备对象,驱动程序使用设备对象来与系统和其他驱动程序进行通信。参数:需要提供设备扩展名和设备的类型、特征以及......
  • 1025 反转链表
    我看其他博客用的reverse,但是下标我真的有点糊涂,以下是参考某位dalao的。#include<bits/stdc++.h>usingnamespacestd;structnode{ intsno; intdata; intnext;}s[100010];intmain(){ intstart,cnt,fz;//start cin>>start>>cnt>>fz; for(inti=0;i<cnt......
  • C#中 控制反转IOC与依赖注入DI
    一、IOC与DI的关系IOC即控制反转,用来管理项目中对象的生命周期和依赖关系,DI依赖注入,用来实现IOC,IOC是思想,DI是实现,在项目中通常一起出现,像是A类调用B类的方法,IOC容器资源给予对应资源,有助于实现依赖倒置DIP二、DI常用的注入方式(.net的DI默认的是构造函数定义)构造函数注入:构......
  • Linux 64位内核(arm64)驱动兼容32位应用程序(armhf)的ioctl接口
    最近,公司来了一次硬件升级,开发平台从全志T3(armhf)升级到全志T527(arm64),平台迁移后,想直接使用原来动态库和应用程序从而减少开发量,用户态大部分接口都运行正常,唯独ioctl接口无法调用成功。如果要成功移植要做到以下几点:1.驱动要同时实现unlocked_ioctl和compat_ioctl。str......
  • Godot.NET C#IOC重构(3):视差景深背景
    目录相关链接前言目标效果景深效果实现无限长背景重复景深相关链接十分钟制作横版动作游戏|Godot4教程《勇者传说》#0前言这次来学习如何设置景深目标效果景深效果实现无限长背景只要开起了Mirror,Godot就会进行无限自我复制重复景深......