IoC

前言

在讲Ioc前,想必你已经听过或者熟悉下面这些名词了。
image

在说这些名词前,我们先弄清楚两个词的区别:设计原则和设计模式。

设计原则

为软件设计提供高级指导,不提供实现,不受编程语言约束。例如:SOLID(SRP,OCP,LSP,ISP,DIP)原则。
例如,单一责任原则(SRP)表明,一个类应该只有一个原因要改变。这是我们在为应用程序设计或创建类时可以牢记的高级声明。 SRP不提供具体的实施步骤。

设计模式

常为面向对象的问题提供低级解决方案(实现)。换句话说,设计模式为具体的面向对象编程问题提出了具体的实现。
例如,如果要创建一次只能有一个对象的类,那么可以使用Singleton设计模式,这样可以创建一个只能有一个对象的类的最佳方法。

理解之后,我们看下图:

image

紧耦合到松耦合

image

  1. 使用工厂模式实现IoC(控制反转)
  2. 创建抽象层实现DIP(依赖倒置原则)
  3. 实现DI(依赖注入)
  4. 使用IoC容器

举例子

image

public class CustomerBusinessLogic
{
    DataAccess _dataAccess;

    public CustomerBusinessLogic()
    {
        _dataAccess = new DataAccess();
    }

    public string GetCustomerName(int id)
    {
        return _dataAccess.GetCustomerName(id);
    }
}

public class DataAccess
{
    public DataAccess()
    {
    }

    public string GetCustomerName(int id) {
        return "Dummy Customer Name"; // get it from DB in real app
    }
}

1.使用工厂模式实现IoC

public class CustomerBusinessLogic
{
    public CustomerBusinessLogic()
    {
    }

    public string GetCustomerName(int id)
    {
        DataAccess _dataAccess = DataAccessFactory.GetDataAccessObj();

        return _dataAccess.GetCustomerName(id);
    }
}

public class DataAccessFactory
{
    public static DataAccess GetDataAccessObj() 
    {
        return new DataAccess();
    }
}

public class DataAccess
{
    public DataAccess()
    {
    }

    public string GetCustomerName(int id) {
        return "Dummy Customer Name"; // get it from DB in real app
    }
}

2.创建抽象层实现DIP

  1. 高级模块不应该依赖于低级模块,两者都应该取决于抽象。
  2. 抽象不应该依赖细节,细节应该取决于抽象。
public interface ICustomerDataAccess
{
    string GetCustomerName(int id);
}

public class CustomerDataAccess: ICustomerDataAccess
{
    public CustomerDataAccess() {
    }

    public string GetCustomerName(int id) {
        return "Dummy Customer Name";        
    }
}

public class DataAccessFactory
{
    public static ICustomerDataAccess GetCustomerDataAccessObj() 
    {
        return new CustomerDataAccess();
    }
}

public class CustomerBusinessLogic
{
    ICustomerDataAccess _custDataAccess;

    public CustomerBusinessLogic()
    {
        _custDataAccess = DataAccessFactory.GetCustomerDataAccessObj();
    }

    public string GetCustomerName(int id)
    {
        return _custDataAccess.GetCustomerName(id);
    }
}

3.实现DI

  • 构造函数注入
  • 属性注入
  • 方法注入

构造函数注入示例:

public class CustomerService
{
    CustomerBusinessLogic _customerBL;

    public CustomerService()
    {
        _customerBL = new CustomerBusinessLogic(new CustomerDataAccess());
    }

    public string GetCustomerName(int id) {
        return _customerBL.GetCustomerName(id);
    }
}

属性注入示例:

public class CustomerBusinessLogic
{
    public CustomerBusinessLogic()
    {
    }

    public string GetCustomerName(int id)
    {
        return DataAccess.GetCustomerName(id);
    }

    public ICustomerDataAccess DataAccess { get; set; }
}

public class CustomerService
{
    CustomerBusinessLogic _customerBL;

    public CustomerService()
    {
        _customerBL = new CustomerBusinessLogic();
        _customerBL.DataAccess = new CustomerDataAccess();
    }

    public string GetCustomerName(int id) {
        return _customerBL.GetCustomerName(id);
    }
}

方法注入示例:

interface IDataAccessDependency
{
    void SetDependency(ICustomerDataAccess customerDataAccess);
}

public class CustomerBusinessLogic : IDataAccessDependency
{
    ICustomerDataAccess _dataAccess;

    public CustomerBusinessLogic()
    {
    }

    public string GetCustomerName(int id)
    {
        return _dataAccess.GetCustomerName(id);
    }
        
    public void SetDependency(ICustomerDataAccess customerDataAccess)
    {
        _dataAccess = customerDataAccess;
    }
}

public class CustomerService
{
    CustomerBusinessLogic _customerBL;

    public CustomerService()
    {
        _customerBL = new CustomerBusinessLogic();
        ((IDataAccessDependency)_customerBL).SetDependency(new CustomerDataAccess());
    }

    public string GetCustomerName(int id) {
        return _customerBL.GetCustomerName(id);
    }
}

4.使用IoC容器

  • MEF
  • Autofac
  • Unity

来源

内容和图片均来自:http://www.tutorialsteacher.com/ioc

原文地址:https://www.cnblogs.com/talentzemin/p/7519060.html