抓蟲系列(五) 淺談依賴注入與控制反轉
2011-10-23 23:09 熬夜的蟲子 閱讀(3404) 評論(1) 收藏 舉報前篇回顧:前篇蟲子介紹了3個"池"中線程池的相關問題,不過謬論的可能性比較大 僅代表蟲子的個人觀點了 - -
本章結合實例給大家闡述下依賴注入與控制反轉可以給自己的項目帶來哪些優缺點。
先回顧下OO的一些設計原則:
開放封閉原則 軟件實體(類、模塊、函數等)應該是可以開展的,但是不可修改。
依賴倒置原則 抽象不應該依賴于細節。細節應該依賴于抽象。
接口隔離原則 不應該強迫客戶依賴于它們不用的方法。接口屬于客戶,不屬于它所在的類層次結構。
單一職責原則 就一個類而言,應該僅有一個引起它變化的原因。
......
隨著面向對象分析與設計的發展,一個良好的設計,核心原則之一就是將變化隔離,使得變化部分發生變化時,不變部分不受影響(這也是OCP的目的)。為了做到這一點,要利用面向對象中的多態性,使用多態性后,客戶類不再直接依賴服務類,而是依賴于一個抽象的接口,這樣,客戶類就不能在內部直接實例化具體的服務類。
但是,客戶類在運作中又客觀需要具體的服務類提供服務,因為接口是不能實例化去提供服務的。就產生了“客戶類不準實例化具體服務類”和“客戶類需要具體服務類”這樣一對矛盾。
依賴注入(Dependency Injection),是這樣一個過程:由于某客戶類只依賴于服務類的一個接口,而不依賴于具體服務類,所以客戶類只定義一個注入點。在程序運行過程中, 客戶類不直接實例化具體服務類實例,而是客戶類的運行上下文環境或專門組件負責實例化服務類,然后將其注入到客戶類中,保證客戶類的正常運行。
OK,概念性的東西已經占了不少篇幅了,下面蟲子結合一個低侵入性、通過配置文件實現注入的實例 來看看實際的效果如何。
BaseClass.cs中提供基本的功能類和接口定義
public interface IocObj
{
TestObj GetTestObj(string QQName);
}
public class TestObj
{
public string QQ { get; set; }
}
Content01.cs中實現一種功能
public class Con1 : IocObj
{
public TestObj GetTestObj(string QQName)
{
return new TestObj { QQ = QQName+" 這是con1" };
}
}
Content02.cs中實現另一種功能
public class Con2 : IocObj
{
public TestObj GetTestObj(string QQName)
{
return new TestObj { QQ = QQName + " 這是con2" };
}
}
下面我們就看看如何進行依賴注入,關于分析xml以及反射等細節處理本篇先暫不介紹,主要介紹下依賴注入帶來的影響與效果
控制臺程序
static void Main(string[] args)
{
var IOCService = ServiceLocator.GetService<IocObj>();
var TestObj = IOCService.GetTestObj("1326194996");
Console.WriteLine("當前用戶的qq為" + TestObj.QQ);
Console.ReadLine();
}
配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="ChongZi" type="ChongZi.Config.ConfigSectionHandler, ChongZi.IOC" />
</configSections>
<ChongZi>
<objects>
<add name="Content01" type="BaseClass.IocObj, BaseClass" mapTo="Content01.Con1, Content01" />
</objects>
</ChongZi>
</configuration>
看結果

修改下配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="ChongZi" type="ChongZi.Config.ConfigSectionHandler, ChongZi.IOC" />
</configSections>
<ChongZi>
<objects>
<add name="UserServiceLocal" type="BaseClass.IocObj, BaseClass" mapTo="Content02.Con2, Content02" />
</objects>
</ChongZi>
</configuration>
再看結果

結果一目了然,實例也很簡單。但是依賴注入給項目帶來的意義還是很大的。而且通過一些RMI組件我們還可以注入遠程對象、服務。對于分布式開發也提供了積極的解決方案。不過既然是抓蟲系列,當然也要談談這種模式的缺點,首先對象生成的步驟變復雜,其次,涉及反射對性能上也是個損耗。至于大家的項目中是否需要依賴注入和控制反轉,取決于項目對可維護性以及可擴展性的需求。
![]() |
原創作品允許轉載,轉載時請務必以超鏈接形式標明文章原始出處以及作者信息。 作者:熬夜的蟲子 點擊查看:博文索引 |

浙公網安備 33010602011771號