IoC

前言html

在講Ioc前,想必你已經聽過或者熟悉下面這些名詞了。
imagegit

在說這些名詞前,咱們先弄清楚兩個詞的區別:設計原則和設計模式。github

設計原則

爲軟件設計提供高級指導,不提供實現,不受編程語言約束。例如:SOLID(SRP,OCP,LSP,ISP,DIP)原則。
例如,單一責任原則(SRP)代表,一個類應該只有一個緣由要改變。這是咱們在爲應用程序設計或建立類時能夠牢記的高級聲明。 SRP不提供具體的實施步驟。web

設計模式

常爲面向對象的問題提供低級解決方案(實現)。換句話說,設計模式爲具體的面向對象編程問題提出了具體的實現。
例如,若是要建立一次只能有一個對象的類,那麼能夠使用Singleton設計模式,這樣能夠建立一個只能有一個對象的類的最佳方法。編程

理解以後,咱們看下圖:canvas

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);
    }
}

屬性注入示例:ruby

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);
    }
}

方法注入示例:markdown

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/iocapp

相關文章
相關標籤/搜索