Unity构造函数注入

时间:2014-01-30 15:57:06

标签: c# wpf mvvm unity-container prism

我在使用MVVM的wpf应用程序中使用Prism + Unity。我是Prism和Unity的初学者。

我希望能够关闭当前视图。我读过的各种解决方案和文章指出,最好的方法是从视图模型中进行。但是视图模型需要区域管理器对象才能关闭视图。好的,让我们设置构造函数注入。从来没有尝试过这个,但是有很多关于SO的问题可以解决这个问题。

首先让我解释一下如何将事物连接在一起。我有一个bootstrapper类来处理类型和实例的注册。

以下是我的视图和视图模型的注册方式:

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"));

我仍然是IoC和DI的初学者。有没有我错过的东西?

1 个答案:

答案 0 :(得分:5)

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;
}