事實上,倒不如通過服務的構造函數傳遞一個信息庫的服務,像這樣:
public class Service
{
private readonly IRepository<WWW> _repository;
public Service(IRepository<WWW> repository)
{
_repository = repository;
}
/* the rest is unchanged */
}
Tipically,代表UI將採取服務依賴的類,所以代碼可能是這樣的:
public class UIClass : BaseClassDictatedByCurrentUIFramework
{
private readonly Service _service;
public UIClass(Service service)
{
_service = service;
}
/* UI code that will eventually call methods on the service */
}
你下一步要做的是配置控制容器的反轉,這將知道如何解決餵養日IRepository的實例(和em適當的DataContext實例,如果需要的話)。
例如,如果我們的UI代碼是MVC3控制器,我們會告訴容器解析此控制器的一個實例。這是發生了什麼:
容器注意到在Service
的依賴(構造函數中),並試圖解決它。
由於Service
是一個具體的類,容器將試圖解決它,然後 注意到對IRepository<WWW>
的依賴關係。
IRepository
的分辨率,因爲這是一個接口,要求容器先前已經被設置爲「知道」什麼時候被要求返回一個實例。通常,這只是界面和它的具體實現之間的映射。在我們的情況下,具體實施是Repository<WWW>
和容器也負責「知道」如何實例所需DataContext
實例它(這也必須事先配置)
有一個庫實例,然後將容器能夠正確實例化第一個Service
,然後是控制器類。
注意具體類的自動分辨率功能不是所有的IoC容器有;有些需要顯式配置才能這樣做。
除此之外,我認爲Service
類在您的情況下不會增加太多價值。它只包含由存儲庫實現的方法的委託。在這種情況下,最好讓UI直接依賴IRepository<WWW>
並簡單地刪除Service
類。 但是,如果這個Service
類只是一個例子,並且在您的真實項目中它實現了實際的業務規則,那麼它應該保留。
更新:如何解決ASP中的依賴關係。Net Webforms
上面介紹的例子是理想的依賴注入場景。例如,在ASP.NET MVC中,BaseClassDictatedByCurrentUIFramework將是Controller
- 在這種情況下,框架允許我們控制實例化控制器的組件,因此我們可以在構造函數中注入自己的依賴項。
但是,ASP.Net WebForms不是一個非常友好的框架。它要求每個Page
都需要有一個默認構造函數,這使得所有的構造函數注入想法都不合適。
在這種情況下,一個可能的解決方案如下妥協:
- 實例在應用程序啓動(在Globals.asax)IoC容器,並通過一些全局狀態可用它(例如,應用程序上下文)在
Page
類
- 聲明依賴爲
private readonly
領域,但構造不會有相應的參數(這將在根本沒有參數)
- 在構造函數體:
- 得到IoC容器的參考(可從全局狀態)
- 使用容器來解決所有依賴性的類有
請注意,這種方法需要的學科 - 它很容易在構造函數的其他地方使用容器來解析其他組件。這種方法稱爲服務定位器,它被認爲是反模式(http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx),因此應該避免。
感謝您的回覆。在UIClass示例中,這將如何在傳統的ASP.net應用程序中工作? – Jason 2012-01-12 23:04:42
@Jason:我編輯了我的答案,以包含在ASP.NET WebForms中執行依賴注入的一種可能的解決方案。關於這個主題的更高級的話題,我推薦一本好書 - Mark Seemann的「.NET中的依賴注入」 – GolfWolf 2012-01-13 09:18:22