1

我有一個基於MVVM與Caliburn.Micro和Ninject的WPF應用程序。我有一個名爲ShellViewModel的根視圖模型。它有幾個依賴關係(通過構造函數注入),它們在Caliburn的Bootstrapper中配置。到現在爲止還挺好。動態創建對象時避免服務定位器反轉控制

在某個地方,有一個MenuViewModel和一些按鈕,然後依次打開其他視圖模型。這些視圖模型不是在創建根對象時創建的,但我仍然想從IoC容器注入依賴關係。

我已閱讀service locator vs dependency injection上的這個問題,並且理解了所提出的觀點。

我在印象之下,但是我的MenuViewModel需要能夠訪問我的IoC容器,以便正確地注入正在動態創建的視圖模型..這是我試圖避免的。有另一種方法嗎?

回答

1

是的,我相信你可以做點更好的事情。

考慮如果沒有按需要求,那麼顯然你可以讓這些視圖模型依賴於MenuViewModel等等,直到你到達對象圖的根(ShellViewModel)並且容器將連線一切都起來。

您可以在對象圖中放置一個「防火牆」,只需將可構造依賴項MenuViewModel的內容替換爲依賴關係本身即可。容器是這項工作的明顯選擇,恕我直言,從實際的角度來看,這是一個足夠好的解決方案,即使它不是純粹的。

但是你也可以用一個特殊用途的工廠代替容器;此工廠將取決於容器,併爲MenuViewModel實際相關性提供只讀屬性。訪問這些屬性將導致容器解析對象並返回它們(訪問器方法也可以工作,而不是屬性;更合適的是完全的另一個討論,所以只要使用你認爲更好的方法)。

看起來您並未真正改變現狀,但情況並不相同,如果MenuViewModel直接依賴容器,情況將會如此。在這種情況下,你根本不知道什麼MenuViewModel真正的依賴關係是通過看它的公共接口,而現在你會看到有像

interface IMenuViewModelDependencyFactory 
{ 
    public RealDependencyA { get; } 
    public RealDependencyB { get; } 
} 

的東西的依賴這是更爲翔實。如果你看一下具體MenuViewModelDependencyFactory東西的公共接口也好得多:

class MenuViewModelDependencyFactory : IMenuViewModelDependencyFactory 
{ 
    private Container container; 

    public MenuViewModelDependencyFactory(Container container) { ... } 

    public RealDependencyA { get { ... } } 
    public RealDependencyB { get { ... } } 
} 

應該有在什麼MenuViewModelDependencyFactory打算在這裏與容器做的,因爲它是如此的高度專業化的沒有混亂。

+0

我之前已經看過這種工廠類型的方法,但實際上並沒有在界面中指定依賴關係,相當整潔。 – diggingforfire