2014-01-30 79 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