2009-11-10 171 views
4

我有一個ASP.NET頁面實現我的視圖,並在頁面構造函數中創建演示者。 Phil Haack's post providing was used as the starting point,我只是通過帖子中的例子來說明問題。ASP.NET MVP注入服務依賴關係

public partial class _Default : System.Web.UI.Page, IPostEditView { 

    PostEditController controller; 
    public _Default() 
    { 
     this.controller = new PostEditController(this, new BlogDataService()); 
    } 
} 

什麼是注入BlogDataService實例的最佳方法?我發現這些例子在Page類中使用屬​​性標記了依賴注入框架解析的屬性。

但是,我更喜歡使用構造函數方法進行測試。

有沒有人有輸入或可能鏈接到上述的良好實施。我寧願Ninject,但StructureMap或Windsor只要流利就可以。

感謝您的任何反饋意見。

回答

1

如果您使用Microsoft ServiceLocator,則可以應用service locator design pattern並向容器詢問該服務。

在你的情況下,它會是這個樣子:

public partial class _Default : System.Web.UI.Page, IPostEditView { 

    PostEditController controller; 
    public _Default() 
    { 
     var service = ServiceLocator.Current.GetInstance<IBlogDataService>(); 
     this.controller = new PostEditController(this, service); 
    } 
} 

服務定位有溫莎城堡和StructureMap實現。不確定Ninject,但爲新的IoC創建ServiceLocator適配器並不重要。

+0

我喜歡它,謝謝。 – blu

+0

使用這種方法,該視圖現在知道IBlogDataService,它只應由演示者知道。有沒有辦法使用傳遞當前視圖對象和配置的IBlogDataService實例的DI容器來構造演示者? – Scott

+0

使用服務定位器被認爲是IoC的反模式。一定有更好的方法。 –

1

我還沒有看到在webforms上進行構造函數注入的通用方法。我認爲它可能通過PageFactory實現,但由於現在大多數邊緣正在轉向MVC而不是webforms,這可能不會發生。

然而,autofac(一DI容器我想了很多)具有integration module for ASP.NET WebForms,做財產注入不帶屬性 - 你的代碼應該是這樣的:

public partial class _Default : System.Web.UI.Page, IPostEditView { 

    public IBlogDataService DataService{get;set;} 
    public _Default() 
    { 
    } 
} 

我知道這並不具體解決你的慾望使用構造函數注入,但這是我所知最接近的。

+0

容器保證在構造函數代碼被調用之前設置屬性嗎?感覺有點雞和雞蛋給我。 – blu

+0

不,該屬性將在構造函數被調用後設置。恐怕網絡表單的一個難題就是恐懼。 –

+0

我結束了使用autofac而不是ServiceLocator,但在Neil上面的樣式。謝謝你。 – blu

2

在我們自己開發的MVP框架中,我們有一個類型化的基類,所有頁面都從中繼承。該類型需要是Presenter類型(我們的基本演示者類)

在基類中,我們然後使用IoC容器初始化控制器。

示例代碼:

public class EditPage : BasePage<EditController> { 
} 

public class EditController : Presenter { 
public EditController(IService service) { } 
} 

public class BasePage<T> : Page where T: Presenter 
{ 
T Presenter { get; set; } 
public BasePage() { 
    Presenter = ObjectFactory.GetInstance<T>(); //StructureMap 
} 
} 

希望這有助於!