介绍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。。。