首页 > 其他分享 >依赖倒置原则的基本用法和介绍

依赖倒置原则的基本用法和介绍

时间:2024-04-24 09:47:02浏览次数:22  
标签:依赖 接口 用法 依赖于 倒置 public 注入

依赖倒置原则(Dependency Inversion Principle,DIP)是面向对象设计和软件工程中五大基本原则(SOLID原则)之一。该原则主要强调了两个关键方面:

  1. 高层模块不应该依赖于低层模块,它们两者都应该依赖于抽象
  2. 抽象不应该依赖于细节,细节应该依赖于抽象

在C#中实现依赖倒置原则,通常涉及以下几个关键概念:

  • 接口和抽象类:这些是用于定义抽象的主要工具。
  • 依赖注入:一种将依赖项(如服务、数据访问对象等)传递给需要它们的对象的技术。

以下是一个简单的C#示例,演示了如何应用依赖倒置原则:

假设我们有一个IReader接口和一个FileReader类,它实现了这个接口:

public interface IReader  
{  
    string Read();  
}  
  
public class FileReader : IReader  
{  
    public string Read()  
    {  
        // 读取文件的逻辑  
        return "File content";  
    }  
}

 接下来,我们有一个DocumentProcessor类,它依赖于IReader接口而不是具体的FileReader类:

public class DocumentProcessor  
{  
    private readonly IReader _reader;  
  
    public DocumentProcessor(IReader reader)  
    {  
        _reader = reader;  
    }  
  
    public void Process()  
    {  
        string content = _reader.Read();  
        // 处理内容的逻辑  
    }  
}

在这个例子中,DocumentProcessor类不直接依赖于FileReader类。相反,它依赖于IReader接口。这意味着我们可以轻松地用另一个实现IReader接口的类替换FileReader,而无需修改DocumentProcessor类。

为了将FileReader的实例传递给DocumentProcessor,我们可以使用依赖注入(Dependency Injection,DI)。这通常是通过构造函数、属性或方法参数来完成的。在更复杂的场景中,我们可能会使用DI容器来自动解析和注入依赖项。

使用依赖倒置原则的好处是:

  • 解耦:降低了类之间的耦合度,使得代码更易于测试和维护。
  • 灵活性:可以更容易地替换实现,从而支持多种不同的场景或配置。
  • 可测试性:允许我们创建模拟(mocks)或存根(stubs)来测试那些依赖于外部系统或资源的类。

总之,依赖倒置原则鼓励我们编写更加灵活和可维护的代码,通过抽象和依赖注入来减少代码之间的直接依赖。

如何在C#中实现依赖倒置原则

依赖倒置原则(Dependency Inversion Principle, DIP)主要涉及到接口的使用和依赖注入(Dependency Injection, DI)。以下是一个简单的步骤和示例来说明如何在C#中遵循DIP:

步骤

  1. 定义接口:首先,定义你需要的抽象接口。这些接口描述了高层模块所依赖的行为。

  2. 创建实现:然后,创建实现这些接口的类。这些类提供了具体的行为。

  3. 高层模块依赖于接口:编写高层模块的代码,使其依赖于抽象接口而不是具体的实现类。

  4. 使用依赖注入:在运行时,将具体的实现类注入到高层模块中。这可以通过构造函数注入、属性注入或方法注入来实现。示例

 

假设我们有一个ILogger接口和一个ConsoleLogger类,以及一个依赖于ILoggerAppService类。

定义接口

public interface ILogger  
{  
    void Log(string message);  
}

创建实现

public class ConsoleLogger : ILogger  
{  
    public void Log(string message)  
    {  
        Console.WriteLine(message);  
    }  
}

高层模块依赖于接口

public class AppService  
{  
    private readonly ILogger _logger;  
  
    public AppService(ILogger logger) // 构造函数注入  
    {  
        _logger = logger;  
    }  
  
    public void DoWork()  
    {  
        // 执行一些工作...  
        _logger.Log("Work done!"); // 使用接口而不是具体实现  
    }  
}

使用依赖注入

在应用程序的启动或配置部分,你需要实例化ConsoleLogger并将其注入到AppService中。这可以通过多种方式实现,例如直接在代码中手动注入,或者使用依赖注入框架(如Unity, Autofac, Ninject等)。

手动注入示例:

class Program  
{  
    static void Main(string[] args)  
    {  
        ILogger logger = new ConsoleLogger(); // 创建实现类的实例  
        AppService appService = new AppService(logger); // 将实现类注入到高层模块中  
        appService.DoWork(); // 执行工作,这会调用logger的Log方法  
    }  
}

使用依赖注入框架通常会使这个过程更加自动化和可配置。例如,在ASP.NET Core中,依赖注入是内置的,你可以在Startup.cs中配置服务,然后在需要的地方通过构造函数注入。

依赖注入框架

依赖注入框架可以帮助你管理依赖关系,自动解析和注入依赖项。这些框架通常提供了配置服务、解析服务和生命周期管理等功能。使用依赖注入框架可以极大地简化依赖管理,并使代码更加清晰和可维护。

总结

通过遵循依赖倒置原则并使用接口和依赖注入,你可以编写出更加灵活、可测试和可维护的代码。这样的代码更容易扩展和重构,因为它减少了类之间的耦合度,并允许你轻松地替换实现而不影响其他代码。

标签:依赖,接口,用法,依赖于,倒置,public,注入
From: https://www.cnblogs.com/forges/p/18154378

相关文章

  • 从依赖倒置原则到IOC控制反转实现
    从依赖倒置原则(DependencyInversionPrinciple,DIP)到控制反转(InversionofControl,IoC)再到依赖注入(DependencyInjection,DI)的演进过程,我们可以理解为一种逐步抽象和解耦的设计思想。这种思想在C#等面向对象的编程语言中得到了广泛的应用。首先,让我们回顾一下依赖倒置原则。......
  • IDEA pom.xml依赖警告
    IDEA中,有时pom.xml中会出现如下提示:IDEA2022.1升级了检测易受攻击的Maven和Gradle依赖项,并建议修正,通过插件PackageChecker捆绑到IDE中。这并不是引用错误,不用担心。如果实在强迫症不想看到这个提示,有两个解决办法:卸载PackageChecker插件,再重启IDEA即可。......
  • Flask基本用法
    Flask基本结构#引入Flask包,使得我们可以创建Flask应用实例fromflaskimportFlask#创建一个Flask应用实例。`__name__`是Python内置变量,它表示当前模块的名称。#在这里,`__name__`被传递给Flask构造函数,用于确定应用程序的基本目录(如静态文件和模板的查找路径),尤其是在......
  • 【Java定时任务】浅谈CronTrigger的用法和在线Cron表达式生成网址
    1.CronTrigger的作用CronTriggers往往比SimpleTrigger更有用,如果您需要基于日历的概念,而非SimpleTrigger完全指定的时间间隔,复发的发射工作的时间表。CronTrigger,你可以指定触发的时间表如“每星期五中午”,或“每个工作日9:30时”,甚至“每5分钟一班9:00和10:00逢星期一上午,星期三......
  • typedef用法
    在C语言中,typedef是一个关键字,用于为已有的数据类型创建一个新的名称。它可以简化代码,提高可读性,并使代码更具可维护性。typedef的用法如下:1、为基本数据类型创建别名:typedef可以为基本数据类型(如int、float、char等)创建别名,使其在代码中使用起来更加直观。typedefintmyI......
  • mysql视图的基本用法
    MySQL视图(View)是一种虚拟的表,它基于一个或多个实际表的查询结果构建而成。视图可以像表一样被查询,但实际上它并不存储数据,而是根据定义时指定的查询规则动态生成结果。MySQL视图的基本用法包括创建视图、查询视图、更新视图以及删除视图。以下是MySQL视图的基本用法:创建视图(Crea......
  • Qdrant用法;Qdrant在langchain里的用法
    基础用法这里不再赘述了。直接参照官网。想看看一些概率可以参考下面两个网站:1. https://m.elecfans.com/article/2078558.html2. https://blog.csdn.net/cxs812760493/article/details/135346390下面说一些在langchain可能遇到的问题:1.先确定自己 Collections中向量 的......
  • mysql中last_insert_id()用法
    前言在使用MySQL时,若表中含自增字段(auto_increment类型),则向表中insert一条记录后,可以调用last_insert_id()来获得最近insert的那行记录的自增字段值。但事实上,使用last_insert_id()时有很多注意事项,很容易踩到坑。数据准备CREATETABLE`tb_product`(`id`bigin......
  • 200 Smart的一些关于寄存器和地址相关的用法实例
    累加器200smart有AC0AC1AC2AC3四个累加器,不能作为位访问累加器大小均是32位累加器的数值不会自动清零,中断会保持并重新装载累加器(进入中断时先把原来的值保存起来,退出中断程序后恢复原程序)只有AC1/AC2/AC3可以用作指针AC0不用作指针,不用作间接寻址LDSM0.0......
  • npm link 用法
    1、什么时候使用npmlink?npmlink用来在本地项目和本地npm包之间建立连接,可以在本地进行模块测试。npm包在开发和迭代更新时,不适合直接发布到线上或者直接发布测试版本进行调试,会导致过程繁琐且版本号过多。此时我们就可以使用npmlink命令将包放在no......