介紹Unity框架之前,先要說幾個概念DIP依賴倒置原則、IOC控制反轉、DI依賴注入
DIP是設計原則之一,定義:上層不應該依賴於底層,兩者都依賴於抽象; 抽象不依賴於細節,細節應該依賴於抽象。
像這種設計原則的定義,干巴巴的看,很難整明白,必須結合實際例子才能理解;
以人們用華為手機通信為例:
class HuaWei { public void Dial() { System.Console.WriteLine("華為手機撥號。。"); } } class Person { private HuaWei phone = new HuaWei(); public void Communicate() { phone.Dial(); } }
在這個例子中,Person屬於上層,HUAWEI屬於底層,上層依賴於底層,假設底層發生變動,華為手機壞了,需要更換手機進行通信,我們就需要修改Person代碼;后面再發生底層變動,Person還需要變化
像這種簡單場景下,修改的代價還值得忍受,如果是一個復雜系統,這種頻繁變動的代價是昂貴的。
這個時候,我們就需要把變化封裝,Person不再依賴於Huwei,而是依賴於抽象接口,HUAWEI也依賴於這個抽象接口。 這就是依賴倒置原則。
interface IPhone { void Dial(); } class HuaWei:IPhone { public void Dial() { System.Console.WriteLine("華為手機撥號。。"); } } class Person { private IPhone phone; public Person(IPhone phone) { this.phone = phone; } public void Communicate() { phone.Dial(); } }
還是最初的例子,Person因為依賴於Huwei,需要在Person內部new一個HUAWEI對象才能使用,這種耦合性非常大,IOC就是將new一個Huawei對象的操作交給另外一個容器去處理,我們只是從容器獲取這個對象,這就叫控制反轉。
DI依賴注入是IOC的實現方式,可以是構造器注入,屬性注入,也可以是方法注入
Unity就是.net平台下,開源的IOC框架。
不多說,一步步上代碼。
我們以DataBase組件和Log組件為原型,實現Unity框架的演示Demo
namespace UnityLib { public interface ILog { void WriteLog(string msg); void WriteLog(Exception ex); } }
public class ConsoleLog:ILog { public void WriteLog(string msg) { Console.WriteLine("Console Log" + msg); } public void WriteLog(Exception ex) { Console.WriteLine("Console Log:" + ex.StackTrace); } }
public class FileLog:ILog { public void WriteLog(string msg) { Console.WriteLine("File Log:" + msg); } public void WriteLog(Exception ex) { Console.WriteLine("File Log:" + ex.StackTrace); } }
namespace UnityLib { public interface IDataBase { void Add(); void Delete(); void Update(); void Query(); } }
namespace UnityLib { public class EFDataBase:IDataBase { public void Add() { Console.WriteLine("EF Add"); } public void Delete() { Console.WriteLine("EF Delete"); } public void Update() { Console.WriteLine("EF Update"); } public void Query() { Console.WriteLine("EFUpdate"); Console.WriteLine(" Query"); } } }
namespace UnityLib { public class SQLServerDataBase:IDataBase { public void Add() { Console.WriteLine("SQLServer Add"); } public void Delete() { Console.WriteLine("SQLServer Delete"); } public void Update() { Console.WriteLine("SQLServer Update"); } public void Query() { Console.WriteLine("SQLServer Query"); } } }
配置文件:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" /> </configSections> <unity> <typeAliases> <typeAlias alias="IDataBase" type="UnityLib.IDataBase,UnityLib" /> <typeAlias alias="EFDataBase" type="UnityLib.EFDataBase,UnityLib" /> <typeAlias alias="SQLServerDataBase" type="UnityLib.SQLServerDataBase,UnityLib" /> <typeAlias alias="ILog" type="UnityLib.ILog,UnityLib" /> <typeAlias alias="FileLog" type="UnityLib.FileLog,UnityLib" /> <typeAlias alias="ConsoleLog" type="UnityLib.ConsoleLog,UnityLib" /> </typeAliases> <containers> <container name="DBcontainer"> <type type="IDataBase" mapTo="EFDataBase" name="EF"></type > <type type="IDataBase" mapTo="SQLServerDataBase" name="SQLServer"></type > </container> <container name="LogContainer"> <type type="ILog" mapTo="FileLog" name="file"></type> <type type="ILog" mapTo="ConsoleLog" name="console"></type> </container> </containers> </unity> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" /> </startup> </configuration>
客戶端代碼:
class Program { static void Main(string[] args) { UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); var logContainer = new UnityContainer(); var dbContainer = new UnityContainer(); section.Configure(logContainer, "LogContainer"); section.Configure(dbContainer, "DBcontainer"); var log = logContainer.Resolve<ILog>("console"); var db = dbContainer.Resolve<IDataBase>("EF"); log.WriteLog("測試信息"); db.Add(); } }
以上是Unity框架的簡單應用,代碼沒有深入研究,僅作為一個入門供大家參考。
注:以上是Unity3.X。。。