我試圖讓我的業務邏輯組件查詢服務時,他們被添加到我的窗體/控件類之一。例如,我的庫中可能有一個ClientManager
類,它封裝了一些業務邏輯。它需要一個ILoginManager
實例來查詢它需要操作的一些數據。如何在WinForms應用程序中使用System.ComponentModel中的服務定位器實現進行依賴項注入?
具體ILoginManager
實例是在WinForms應用程序中創建的,例如作爲一個單例。我希望能夠將一個ClientManager
組件放置到表單上,這將使ILoginManager
實例可以自動用於組件。
從我從this article on lightweight containers明白,我可以用GetService的實現這一點:
public class ClientManager : Component
{
public ClientManager() {}
public ClientManager(IContainer container) {
container.Add(this);
}
public ILoginManager User
{
// would really be cached in a private field
get { return GetService(typeof(ILoginManager)) as ILoginManager; }
}
// does something that requires the User property to be set
public void DoSomething();
}
我將不得不重寫的GetService返回我的實例的容器:
public class MyContainer : Container
{
ServiceContainer svc;
public MyContainer() {
svc = new ServiceContainer();
svc.AddService(typeof(ILoginManager), GlobalAppStuff.LoginManager);
}
protected override object GetService(Type service) {
return svc.GetService(service);
}
}
作爲一個獨立的解決方案,這工作得很好,但我無法弄清楚如何將其集成到一個可設計的控件中,因爲設計器始終生成一個默認的容器,並且我不知道有任何向其中注入服務的方法。
MSDN文檔在描述應該如何實際使用這些概念時含糊不清。有什麼簡單的方法可以使用設計器友好的ComponentModel類來完成此操作嗎?
城堡不允許我到我的組件拖動到一個形式,因爲它使用了構造函數注入。 StructureMap使用了一個我不喜歡的靜態對象,因爲它將我的對象專門綁定到StructureMap。看起來基本的.NET組件已經支持我需要的大部分內容,這只是讓它與設計師合作的麻煩。 – 2009-09-22 11:46:55
也許,但即使這很困難,它也只會*在設計師身上工作。運行時IComponent.Site將爲空,但它是提供IServiceProvider實現的ISite值,所以它不會在運行時工作。 – 2009-09-22 12:46:06
我不確定這就是它的全部。設計師沒有設置ISite - 容器。設計人員在設計時使用自己的System.ComponentModel.Design.DesignerHost容器。一個應該能夠在運行時提供自己的容器,並且Visual Studio實際上爲其生成代碼,但是我不知道如何覆蓋它生成的容器類型。 – 2009-09-22 13:35:51