2014-01-30 231 views
0

我在使用MVVM的wpf應用程序中使用Prism + Unity。我是一名棱鏡和統一的初學者。Unity構造函數注入

我希望能夠關閉當前視圖。我讀過的各種解決方案和文章都指出,最好的方法是從視圖模型。但是視圖模型需要一個區域管理器對象來關閉視圖。好的,讓我們設置構造函數注入。從來沒有嘗試過,但有很多關於SO的問題可以解決這個問題。

讓我從解釋事物如何連接在一起開始。我有一個引導類來處理類型和實例的註冊。

下面是如何我的觀點和看法模型註冊:

container.RegisterType<IViewModel, ViewAccountsViewModel>(new InjectionConstructor(new ResolvedParameter(typeof(RegionManager)))); 
container.RegisterType<ViewAccountsView>(); 

下面是該視圖的模塊佔觀點:

public class ViewAccountsModule : IModule 
{ 
    private readonly IRegionManager regionManager; 
    private readonly IUnityContainer container; 

    public ViewAccountsModule(IUnityContainer container, IRegionManager regionManager) 
    { 
     this.container = container; 
     this.regionManager = regionManager; 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    public void Initialize() 
    { 
     regionManager.RegisterViewWithRegion("MainRegion",() => this.container.Resolve<ViewAccountsView>()); 
    } 
} 

在我ViewAccountsView.xaml,我設置了數據背景像這樣:

<Grid.DataContext> 
    <vm:ViewAccountsViewModel/> 
</Grid.DataContext> 

我的視圖模型構造:

[InjectionConstructor] 
public ViewAccountsViewModel(IRegionManager regionManager) 
{ 
    if (regionManager == null) throw new ArgumentNullException("regionManager"); 

    this.regionManager = regionManager; 
} 

當我編譯解決方案時,收到錯誤,類型「ViewAccountsViewModel」不包含任何可訪問的構造函數。如果我添加一個默認的構造函數到我的視圖模型,視圖顯示,但我不能刪除該區域的視圖。我得到一個參數爲null的異常。

這裏是去除視圖代碼:

regionManager.Regions["MainRegion"].Remove(regionManager.Regions["MainRegion"].GetView("ViewAccountsView")); 

我還是非常符合國際奧委會和DI初學者。有什麼我錯過了嗎?

+0

添加一個默認的構造函數,並把破發點上這個constuctor。如果這樣做會(在斷點處停止)比註冊時出錯(檢查所有需要註冊的對象)。 –

+0

我想補充說,如果我改變'container.RegisterType ();'我的視圖顯示,但我不能刪除視圖。我重載的構造函數不會被調用。 –

回答

4

Unity會處理注入它所知道的所有依賴關係。默認情況下,Unity將使用最多的參數調用構造函數。您通常使用InjectionConstructor來告訴Unity在爲您創建對象時選擇不同的構造函數,或者如果您想傳遞它自定義參數。

報名:

container.RegisterType<IViewModel, ViewAccountsViewModel>(); 
// If you plan to have multiple IViewModels, it will need to have a name 
// container.RegisterType<IViewModel, ViewAccountsViewModel>("ViewAccountsViewModelName"); 
container.RegisterType<ViewAccountsView>(); 

視圖模型:

// If you decide later you need other dependencies like IUnityContainer, you can just set 
// it in your constructor and Unity will give it to you automagically through the power 
// of Dependency Injection 
// public ViewAccountsViewModel(IRegionManager regionManager, IUnityContainer unityContainer) 
public ViewAccountsViewModel(IRegionManager regionManager) 
{ 
    this.regionManager = regionManager; 
} 

查看代碼背後:

// If you have a named IViewModel 
// public ViewAccountsView([Dependency("ViewAccountsViewModelName")]IViewModel viewModel) 
public ViewAccountsView(IViewModel viewModel) 
{ 
    this.InitializeComponent(); 
    this.DataContext = viewModel; 
} 
+0

非常感謝您的回答。它爲我工作。 – Snesh