jjzjj

C#依赖注入(直白明了)讲解 一看就会系列

蕉仔世界 2023-03-28 原文

最基础的:UI-BLL-DAL

 

这是我们耳熟能详的分层

(补充:)  我们的类正常都不是孤立存在的。很多都是要依赖于其它的类。 比如说我们有一个Work类,Work类在工作的时候需要把信息记录下来。 MessageWriter就是 Worker的依赖项

 

首先我听到依赖注入之后看似非常的复杂

 

实际则是:为了实现不同的团队在不同的层上工作。我们可以让一个团队处理数据访问层,一个团队处理业务层,一个团队处理UI。 

 

首先建立:最基本的三层架构

实体层:

public class Product
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

 

数据层:DAL

public class ProductDAL
{
    private readonly List<Product> _products;

    public ProductDAL()
    {
        _products = new List<Product>
        {
            new Product { Id = Guid.NewGuid(), Name= "iPhone 9", 
                          Description = "iPhone 9 mobile phone" },
            new Product { Id = Guid.NewGuid(), Name= "iPhone X", 
                          Description = "iPhone X mobile phone" }
        };
    }

    public IEnumerable<Product> GetProducts()
    {
        return _products;
    }

    public IEnumerable<Product> GetProducts(string name)
    {
        return _products
            .Where(p => p.Name.Contains(name))
            .ToList();
    }
}l

 

逻辑层:BLL

public class ProductBL
{
    private readonly ProductDAL _productDAL;

    public ProductBL()
    {
        _productDAL = new ProductDAL();
    }

    public IEnumerable<Product> GetProducts()
    {
        return _productDAL.GetProducts();
    }

    public IEnumerable<Product> GetProducts(string name)
    {
        return _productDAL.GetProducts(name);
    }
}

 

UI层:UI

class Program
{
    static void Main(string[] args)
    {
        ProductBL productBL = new ProductBL();

        var products = productBL.GetProducts();

        foreach (var product in products)
        {
            Console.WriteLine(product.Name);
        }

        Console.ReadKey();
    }
}

 

  以上就是我们基础的结构:  UI - BLL - DAL  引用顺序

那么出现以下三个问题:

1.我们不能让三个不同的团队在每个层上工作。

2.业务层很难扩展,因为它依赖于数据访问层的实现。

3.业务层很难维护,因为它依赖于数据访问层的实现。

 

高级别对象不应该依赖于低级别对象。两者都必须依赖于抽象。那么抽象概念是什么呢?

抽象是功能的定义。在我们的例子中,业务层依赖于数据访问层来检索图书。在C#中,我们使用接口实现抽象。接口表示功能的抽象。

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------以下为修改后结构

数据层:DAL 

DAL:接口

public interface IProductDAL
{
    IEnumerable<Product> GetProducts();
    IEnumerable<Product> GetProducts(string name);
}

 

DAL:实现 

public class ProductDAL : IProductDAL

 

 

业务逻辑层:BLL  这样我们就做到了  使其依赖于IDAL 抽象层,而不是DAL层直接实现:

public class ProductBL
{
    private readonly IProductDAL _productDAL;

    public ProductBL()
    {
        _productDAL = new ProductDAL();
    }

    public IEnumerable<Product> GetProducts()
    {
        return _productDAL.GetProducts();
    }

    public IEnumerable<Product> GetProducts(string name)
    {
        return _productDAL.GetProducts(name);
    }
}

 

 

业务逻辑层:IBLL  (同样的 UI 依赖于BLL 我们也这样做 搞个抽象层 接口)

public interface IProductBL
{
    IEnumerable<Product> GetProducts();
    IEnumerable<Product> GetProducts(string name);
} 

 

同理:更新BLL层:  

public class ProductBL : IProductBL

 

UI层:  就和BLL依赖于DAL一样  UI依赖于BLL

class Program
{
    static void Main(string[] args)
    {
        IProductBL productBL = new ProductBL();

        var products = productBL.GetProducts();

        foreach (var product in products)
        {
            Console.WriteLine(product.Name);
        }

        Console.ReadKey();
    }

 

  

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------以上为抽象层的建立,

 

还记得我们标红的地方吗?

public ProductBL()
{
    _productDAL = new ProductDAL();
}

 

BLL依赖于IDAL  ,但是  最终我们还是依赖于DAL

到目前为止,我们所做的工作都与依赖注入无关 

 

为了使处在BLL依赖于DAL的功能,而没有具体的实现,必须由其他人创建类。其他人必须提供底层对象的具体实现,这就是我们所说的依赖注入。它的字面意思是我们将依赖对象注入到更高级别的对象中。

 

实现依赖项注入的方法之一是使用构造函数进行依赖项注入。

更新业务层:

public class ProductBL : IProductBL
{
    private readonly IProductDAL _productDAL;

    public ProductBL(IProductDAL productDAL)
    {
        _productDAL = productDAL;
    }

    public IEnumerable<Product> GetProducts()
    {
        return _productDAL.GetProducts();
    }

    public IEnumerable<Product> GetProducts(string name)
    {
        return _productDAL.GetProducts(name);
    }
}

 

  

UI:

class Program
{
    static void Main(string[] args)
    {
        IProductBL productBL = new ProductBL(new ProductDAL());

        var products = productBL.GetProducts();

        foreach (var product in products)
        {
            Console.WriteLine(product.Name);
        }

        Console.ReadKey();
    }
}

 

  创建DAL控制与UI结合在一起。这也称为控制反转

我们不是在BLL中创建DAL的实例,而是在UI的中创建它。 Main方法将把实例注入到业务逻辑层。因此,我们将低层对象的实例注入到高层对象的实例中。

                                         这叫做依赖注入

现在,如果我们看一下代码,我们只依赖于业务访问层(BLL)中数据访问层(IDAL)的抽象,而业务访问层(BLL)是使用的是数据访问层实现的接口。因此,我们遵循了更高层次对象和更低层次对象都依赖于抽象的原则,抽象是更高层次对象和更低层次对象之间的契约。

 

接下来就显示了可维护性和可扩展性的好处。例如,如果我们想为SQL Server创建一个新的数据访问层,我们只需实现数据访问层的抽象并将实例注入基础设施中。

 

 

 

原文连接:   www.cnblogs.com/hhhnicvscs/p/14204806.html

原文链接:www.codeproject.com/Articles/5274732/Dependency-Injection-and-IoC-Containers-in-Csharp 

 

有关C#依赖注入(直白明了)讲解 一看就会系列的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  3. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  6. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  7. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  8. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  9. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  10. 阿里云RDS——产品系列概述 - 2

    基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于

随机推荐