天天看點

DI依賴注入設計模式

​​《DIP依賴反轉原則——實作松耦合的設計》​​ 我們通過建立和使用抽象實作了DIP原則,進一步獲得松耦合設計。本單将使用依整注入(DI)設計模式來将依賴的對象的建立徹底移出類外面去,以獲得完全的松耦合的程式設計。

DI依賴注入設計模式

依整注入是一種設計模式。它實作了IOC反轉控制原則。它将依賴的類的建立在類外面實作,再通過注入的方式将建立好的類注入。比如說,A類依賴B類,那麼我們先在A類外面,建立好B類,再将其注入到A類中。注入的方式有三種,在講它們之間,我們規範上各個類的稱呼,比如說上面說的A類,我們稱其為Client類,B類則為Service類,還有一個是連接配接它們的類叫注入器類:

  • Client類: 依賴service類。
  • Service類: 提供服務給Client類。
  • Injector類: 将service類注入到Client類。

注入方式有三種:

  • 構造函數注入: 注入器類(Injector類)将service類通過Client的構造函數注入到Client類中。
  • 屬性注入:注入器類(Injector類)将service類通過Client的公共屬性注入到Client類中。
  • 方法注入:這種方式的注入,需要Client類實作一個接口,它個接口是提供依賴的。注入器類就會使用這個接口将service類注入到Client類。

舉個例子:

我們在前面的實作了DIP的例子上繼續改:

public interface ICustomerDataAccess
{
    string GetCustomerName(int id);
}

public class CustomerDataAccess implements 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);
    }
}      

構造器注入:

// Client類
public class CustomerBusinessLogic
{
    ICustomerDataAccess _dataAccess;

    public CustomerBusinessLogic(ICustomerDataAccess custDataAccess)
    {
        _dataAccess = custDataAccess;
    }

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

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

public interface ICustomerDataAccess
{
    string GetCustomerName(int id);
}

// service類
public class CustomerDataAccess implements ICustomerDataAccess
{
    public CustomerDataAccess()
    {
    }

    public string GetCustomerName(int id) 
    {
        //get the customer name from the db in real application        
        return "Dummy Customer Name"; 
    }
}

// 注入器類
public class CustomerService
{
    CustomerBusinessLogic _customerBL;

    public CustomerService()
    {
    // 通過構造器注入ICustomerDataAccess的執行個體
        _customerBL = new CustomerBusinessLogic(new CustomerDataAccess());
    }

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

屬性注入:

// Client類
public class CustomerBusinessLogic
{
    public CustomerBusinessLogic()
    {
    }

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

    // 屬性
    public ICustomerDataAccess DataAccess;
}

// 注入器類
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);
}

// Client類,實作IDataAccessDependency接口
public class CustomerBusinessLogic implements 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();
        // 通過Client的方法注入。
        ((IDataAccessDependency)_customerBL).SetDependency(new CustomerDataAccess());
    }

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

繼續閱讀