zoukankan      html  css  js  c++  java
  • StructureMap DI & IoC 工具介绍

    假定有这样的案例,电子商务应用程序中检索给定类别中的所有商品。我们很容易给出这样的代码

    示例代码

    product.cs

       1:  public class Product
       2:  {
       3:  }

    ProductRepository.cs

       1:  public IList<Product> GetAllProductIn(int categoryId)
       2:  {
       3:      IList<Product> products = new List<Product>();
       4:   
       5:      //Database operation to populate products;
       6:   
       7:      return products;
       8:  }

    ProductService.cs

       1:  public class ProductService
       2:  {
       3:      private ProductRepository _productRepository;
       4:   
       5:      public ProductService()
       6:      {
       7:          _productRepository = new ProductRepository();
       8:      }
       9:      public IList<Product> GetAllProductIn(int categoryId)
      10:      {
      11:          return _productRepository.GetAllProductIn(categoryId);
      12:      }
      13:  }

    ProductService类负责从资源库中检索出指定类别的商品。

    下面我们来分析这段代码,看看有什么问题。

    用vs生成 依赖项关系图

    2U}3AY9QE]JBGV09TL2AO7E 

    从图中可以看出

    1、ProductService类依赖于ProductRepository,如果ProductRepository类的API发生改变,ProductService就需要相应的更改。

    2、代码不可测试,如果不让真正的ProductRepository类连接到真正的数据库。就不能测试ProductRepository的方法。

    根据设计原则进行重构

    依赖倒置原则:依赖抽象而不要依赖于具体

    创建IProductRepository接口,让ProductRepository与ProductService都依赖于此接口

    IProductRepository接口

       1:  public interface IProductRepository
       2:  {
       3:      IList<Product> GetAllProductIn(int categoryId);
       4:  }

    ProductRepository.cs

       1:  public class ProductRepository :IProductRepository
       2:  {
       3:      //代码同上 
       4:  }

    ProductService.cs

       1:  public class ProductService
       2:  {
       3:      private IProductRepository _productRepository;
       4:   
       5:      public ProductService()
       6:      {
       7:          _productRepository = new ProductRepository();
       8:      }
       9:  }

    依赖项关系图

    CF`M0HKT(E`~{8`9UMIVQ9Y

    通过引入IProductRepository接口,ProductService类只依赖于抽象而不依赖于具体。

    现在ProductService类仍然负责创建具体的实现。

    引入依赖注入

    ProductService类仍然和ProductRepository的具体实现绑定在一起,ProductService类目前还需创建实例。

    依赖注入(Dependency Injection):依赖注入是一个这样的过程,由于客户类(ProductService)只依赖于服务类的一个接口(IProductRepository),而不依赖于具体的服务类(ProductRepository),所以客户类只定义一个注入点。在程序运行过程中,客户类不直接实例化具体的服务类实例,而是客户类的运行上下文环境或专门的组件负责实例化服务类,然后将其注入到客户类中。

    依赖注入的形式

    1、构造器注入

    ProductService.cs

       1:  public class ProductService
       2:  {
       3:      private IProductRepository _productRepository;
       4:   
       5:      public ProductService(IProductRepository productRepository)
       6:      {
       7:          _productRepository = productRepository;
       8:      }
       9:      public IList<Product> GetAllProductIn(int categoryId)
      10:      {
      11:          return _productRepository.GetAllProductIn(categoryId);
      12:      }
      13:  }

    2、方法注入

    ProductService.cs

       1:  public class ProductService
       2:  {
       3:      private IProductRepository _productRepository;
       4:   
       5:      public void SetRepository(IProductRepository productRepository)
       6:      {
       7:          _productRepository=productRepository;
       8:      }
       9:   
      10:      public ProductService( )
      11:      {
      12:      }
      13:      public IList<Product> GetAllProductIn(int categoryId)
      14:      {
      15:          return _productRepository.GetAllProductIn(categoryId);
      16:      }
      17:  }
      18:   

    IoC

    定义:控制反转(Inversion of Control,英文缩写为IoC)是一种设计模式,核心思想是类之间的依赖关系,不再由类自己去负责,而是由容器根据配置文件去创建实例并维护各个实例之间的依赖关系。

    DI是实现IoC的一种方式。

    StructureMap

    StructureMap是一种.Net下的依赖注入框架,当前版本是2.6.1,下载地址https://github.com/structuremap/structuremap/downloads

       1:  public static class ContainerBootstrapper
       2:  {
       3:      public static void BootstrapStructureMap()
       4:      {
       5:          // Initialize the static ObjectFactory container
       6:          ObjectFactory.Initialize(x =>
       7:          {
       8:              x.For<IProductRepository>().Use<ProductRepository>();
       9:          });
      10:      }
      11:  }

    调用

       1:  class Program
       2:  {
       3:      static void Main(string[] args)
       4:      {
       5:          ContainerBootstrapper.BootstrapStructureMap();
       6:          ProductService service = new ProductService(ObjectFactory.GetInstance<IProductRepository>());
       7:          service.GetAllProductIn(2);
       8:          
       9:      }
      10:  }
  • 相关阅读:
    设计模式
    LiggEasyWinApp-104-Ligg.EasyWinForm:Zone
    Ligg.EasyWinApp-10300-Ligg.EasyWinForm:View的配置
    LiggEasyWinApp-103-Ligg.EasyWinForm:View
    Ligg.EasyWinApp-102-Ligg.EasyWinForm:Function--ControlBox、Tray、Resize、Menu
    Ligg.EasyWinApp-101-Ligg.EasyWinForm: Application--启动,传入参数、读取Application级别配置文件、验证密码、软件封面、启动登录、StartForm
    Ligg.EasyWinApp-100-Ligg.EasyWinForm:一款Winform应用编程框架和UI库介绍
    Ligg.WinOa-000: Windows运维自动化编程实战--前言
    Ligg.EasyWinApp-000: 一款Windows应用编程框架介绍
    微服务分布式 spring cloud springboot 框架源码 activiti工作流 前后分离
  • 原文地址:https://www.cnblogs.com/whx1973/p/2754062.html
Copyright © 2011-2022 走看看