【问题标题】:Unity Constructor InjectionUnity 构造函数注入
【发布时间】:2014-01-30 15:57:06
【问题描述】:

我在使用 MVVM 的 wpf 应用程序中使用 Prism + Unity。我是 Prism 和 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”类型不包含任何可访问构造函数的错误。如果我将默认构造函数添加到我的视图模型,则视图会显示,但我无法从该区域中删除该视图。我得到一个参数空异常。

这里是删除视图的代码:

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

我仍然是 IoC 和 DI 的初学者。有什么我遗漏的吗?

【问题讨论】:

  • 添加一个默认构造函数并在这个构造函数上放置断点。如果这可行(在断点处停止)而不是您的注册有问题(检查所有必需的对象,如果它们都已注册)。
  • 我想补充一点,如果我更改为container.RegisterType&lt;IViewModel, ViewAccountsViewModel&gt;();,我的视图会显示,但我无法删除该视图。我的重载构造函数没有被调用。

标签: c# wpf mvvm unity-container prism


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多