基於.net EF6 MVC5+WEB Api 的Web系統框架總結(3)-專案依賴注入
- 簡介
依賴注入主要是一種結構性的模式,注重的是類與類之間的結構,它要達到的目的就是設計原則中最少知道和合成複用的原則,減少內部依賴,履行單一職責,最終就是強解耦。依賴注入目前最好的實現就是依賴注入容器。
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); }
執行測試結果達到工廠模式同樣的效果,並且可擴充套件性更強、專案解耦,減少專案依賴。
至此,專案介紹完畢,更多精彩,且聽下回分