基於.net EF6 MVC5+WEB Api 的Web系統框架總結(3)-項目依賴注入

  • 2019 年 10 月 3 日
  • 筆記
  1. 簡介

  依賴注入主要是一種結構性的模式,注重的是類與類之間的結構,它要達到的目的就是設計原則中最少知道和合成復用的原則,減少內部依賴,履行單一職責,最終就是強解耦。依賴注入目前最好的實現就是依賴注入容器。

  Unity是微軟Patterns & Practices團隊所開發的一個輕量級的,並且可擴展的依賴注入(Dependency Injection)容器,它支援常用的三種依賴注入方式:構造器注入(Constructor Injection)、屬性注入(Property Injection),以及方法調用注入(Method Call Injection).

  本項目基於Unity,減少內部依賴,實現項目解耦。基於LGPL協議開源。

 

  2.項目源碼

using Microsoft.Practices.Unity;  using Microsoft.Practices.Unity.Configuration;  using System;  using System.Collections.Generic;  using System.Configuration;  using System.Linq;  using System.Text;    namespace ShiQuan.Unity  {      /// <summary>      /// Unity 輔助對象      /// </summary>      public class UnityHelper      {          #region 單例            private static readonly UnityHelper _instance = new UnityHelper();          /// <summary>          /// Unity 輔助對象          /// </summary>          public static UnityHelper Instance          {              get              {                  return _instance;              }          }          #endregion            private readonly IUnityContainer _container = new UnityContainer();          /// <summary>          /// 獲取容器          /// </summary>          public IUnityContainer Container          {              get { return _container; }          }          private UnityHelper()          {              var configuration = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;              if (configuration != null)              {                  configuration.Configure(_container);              }          }            #region 獲取對應介面的具體實現類          /// <summary>          /// 獲取實現類(默認映射)          /// </summary>          /// <typeparam name="T">介面類型</typeparam>          /// <returns>介面</returns>          public T GetResolve<T>()          {              return _container.Resolve<T>();          }          /// <summary>          /// 獲取實現類(默認映射)帶參數的          /// </summary>          /// <typeparam name="T">介面類型</typeparam>          /// <param name="parameter">參數</param>          /// <returns>介面</returns>          public T GetResolve<T>(params ParameterOverride[] parameter)          {              return _container.Resolve<T>(parameter);          }          /// <summary>          /// 獲取實現類(指定映射)帶參數的          /// </summary>          /// <typeparam name="T"></typeparam>          /// <param name="name"></param>          /// <param name="parameter"></param>          /// <returns>介面</returns>          public T GetResolve<T>(string name, params ParameterOverride[] parameter)          {              return _container.Resolve<T>(name, parameter);          }          #endregion            #region 判斷介面是否被註冊了          /// <summary>          /// 判斷介面是否被實現了          /// </summary>          /// <typeparam name="T">介面類型</typeparam>          /// <returns>bool</returns>          public bool IsRegistered<T>()          {              return _container.IsRegistered<T>();          }          /// <summary>          /// 判斷介面是否被實現了          /// </summary>          /// <typeparam name="T">介面類型</typeparam>          /// <param name="name">映射名稱</param>          /// <returns></returns>          public bool IsRegistered<T>(string name)          {              return _container.IsRegistered<T>(name);          }          #endregion      }  }

 

  源碼地址:https://gitee.com/ShiQuan25/ShiQuan.Unity

  3.調用示例

  下面演示調用此程式示例:

  首先我們創建數據操作基礎項目,定義IDataBase介面,定義一獲取名稱的方法。

using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.Threading.Tasks;    namespace ShiQuan.DataAccess  {      /// <summary>      /// 定義介面      /// </summary>      public interface IDatabase      {          string Name { get; }      }  }

 

       創建SQLSERVER項目,定義SqlDataBase實現IDatabase介面。

using ShiQuan.DataAccess;  using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.Threading.Tasks;    namespace ShiQuan.DataServer  {      /// <summary>      /// 實現      /// </summary>      public class SqlDataBase : IDatabase      {          public string Name          {              get { return "SqlDataBase"; }          }      }  }

 

  創建MySql 項目,定義MySqlDataBase實現IDatabase介面。

using ShiQuan.DataAccess;  using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.Threading.Tasks;    namespace ShiQuan.DataMySql  {      /// <summary>      /// 實現      /// </summary>      public class MySqlDataBase : IDatabase      {          public string Name          {              get { return "MySqlDataBase"; }          }      }  }

  創建數據操作工廠項目,定義DataFactory實現根據參數調用不同的實現類。

using ShiQuan.DataAccess;  using ShiQuan.DataMySql;  using ShiQuan.DataServer;  using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.Threading.Tasks;    namespace ShiQuan.DataRepository  {      /// <summary>      /// 數據工廠      /// </summary>      public class DataFactory      {          /// <summary>          /// 獲取數據操作對象          /// </summary>          /// <param name="name"></param>          /// <returns></returns>          public static IDatabase GetDataBase(string name)          {              switch (name)              {                  case "MySql":                      {                          return new MySqlDataBase();                      }                  case "SqlServer":                  default:                      {                          return new SqlDataBase();                      }              }            }      }  }

  創建Console程式進行測試

using ShiQuan.DataServer;  using ShiQuan.DataMySql;  using ShiQuan.Unity;  using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.Threading.Tasks;  using ShiQuan.DataAccess;  using ShiQuan.DataRepository;    namespace ConsoleApp  {      class Program      {          static void Main(string[] args)          {              Console.WriteLine("實例並調用Sql Server...");              IDatabase sqlserver = DataFactory.GetDataBase("SqlServer");              Console.WriteLine(sqlserver.Name);                Console.WriteLine("實例並調用MySql...");              IDatabase mysql = DataFactory.GetDataBase("MySql");              Console.WriteLine(mysql.Name);                Console.ReadLine();          }        }  }

  項目結構大概是這樣的:

  運行結果:

  4.Unity調用

  假設此時,如果我們需要實現其他資料庫操作,實現IDatabase介面時,除了增加其他資料庫操作項目,還得修改、調整數據操作工廠項目。

  但是如果我們的數據操作工廠項目改用依賴注入的方式,工廠項目是不需要引用SQLSERVER項目、MySQL項目及其他資料庫操作項目,可以不改動工廠項目的情況下,主程式直接在配置文件中添加相應的操作項目及類,以達到面向介面開發、減少內部依賴、實現項目解耦。

  項目添加程式包

 

  主程式配置文件(App.Config或Web.Config)增加配置

<configSections>      <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration" />    </configSections>

 

  配置介面,介面實現對象

 

<unity>      <typeAliases>        <typeAlias alias="IDatabase" type="ShiQuan.DataAccess.IDatabase,ShiQuan.DataAccess" />        <typeAlias alias="SqlServer" type="ShiQuan.DataServer.SqlDataBase,ShiQuan.DataServer" />        <typeAlias alias="MySql" type="ShiQuan.DataMySql.MySqlDataBase,ShiQuan.DataMySql" />      </typeAliases>      <containers>        <container>          <type type="IDatabase" mapTo="SqlServer" name="SqlServer"></type >          <type type="IDatabase" mapTo="MySql" name="MySql"></type >        </container>      </containers>    </unity>

  工廠項目實例調用

 

/// <summary>          /// 獲取數據操作對象          /// </summary>          /// <param name="name"></param>          /// <returns></returns>          public static IDatabase GetDataBase(string name)          {              //switch (name)              //{              //    case "MySql":              //        {              //            return new MySqlDataBase();              //        }              //    case "SqlServer":              //    default:              //        {              //            return new SqlDataBase();              //        }              //}              return ShiQuan.Unity.UnityHelper.Instance.GetResolve<IDatabase>(name);          }

  運行測試結果達到工廠模式同樣的效果,並且可擴展性更強、項目解耦,減少項目依賴。

 

  至此,項目介紹完畢,更多精彩,且聽下回分解!