在WPF MVVM应用程序中使用Unity进行依赖注入

3
我一直在尝试使用Unity在WPF应用程序中设置依赖注入,但似乎无法完全理解视图和视图模型应该如何设置。
已经查看了另一个SO帖子 -> Wpf Unity,但还不能完全理解。我以前在MVC应用程序中使用过Unity,因此知道如何在构造函数中进行注入。
这是我的应用程序中的视图和视图模型。 Views:
MainWindow.xaml
BookingView.xaml
ContactDetailsView.xaml
ReservationsView.xaml

视图模型:

MenuViewModel (MainWindow uses this viewModel)
BookingViewModel
ContactViewModel
ReservationsViewModel

我的ViewModels都有已实现的接口,例如IMenuViewModel,视图是否也应该有一个接口?

我想既然MainWindow是起点,那么它应该在这里注册容器,对吗?

更新:

我找到了一些东西,但不确定我是否做得正确。以下是我迄今为止所做的!

1:在app.cs中使用启动方法

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        IUnityContainer container = new UnityContainer();

        container.RegisterType<IViewMainWindowViewModel, MainWindow>();
        container.RegisterType<IViewMainWindowViewModel, MenuViewModel>();

        var mainWindow = container.Resolve<MainWindow>(); // Creating Main window
        mainWindow.Show();
    }

}

2:从启动中删除uri。

3:在MainWindow类中创建IViewMainWindowViewModel接口,该接口为空。

public interface IViewMainWindowViewModel
{

}

4:在MainWindow中引用此接口

public partial class MainWindow : Window, IViewMainWindowViewModel
{
    public MainWindow(IViewMainWindowViewModel viewModel)
    {
        InitializeComponent();
        DataContext = viewModel;
    }

5:同时适用于MenuViewModel

public class MenuViewModel : IViewMainWindowViewModel
{
    Code not shown!
}

这将无法启动应用程序。

更新2

我的MainWindow类如下:

public interface IViewMainWindowViewModel
{

}

public partial class MainWindow : Window, IViewMainWindowViewModel
{
    public MainWindow(IViewMainWindowViewModel viewModel)
    {
        InitializeComponent();
        DataContext = viewModel;
    }

App类现在看起来像这样:

protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        IUnityContainer container = new UnityContainer();
        container.RegisterType<IViewMainWindowViewModel, MainWindow>();
        container.RegisterType<IViewMainWindowViewModel, MenuViewModel>();
        container.Resolve<MainWindow>().Show();
        //Do the same actions for  all views and their viewmodels
    }

当运行应用程序时,我在这一行收到了一个异常。
container.Resolve<MainWindow>().Show();

更新3

在我的MenuViewModel中,有两个命令可以打开两个视图,那么我是否需要在MenuViewModel的构造函数中注入这些视图,还是只需要在MenuViewModel和BookingView之间添加另一个空接口即可?

1个回答

2
让我给您展示一个例子,并为您的MainWindows进行解释,至于其他视图和视图模型的步骤是相同的。
首先,您应该在ViewViewModel之间创建合同。它应该是一些接口,并让其命名为IViewMainWindowViewModel(请记住,其他视图和视图模型的名称必须不同,例如IViewBookingViewViewModel):
public interface IViewMainWindowViewModel
{
       /*This interface should not have any methods or commands. It is just 
       contract between View and ViewModels and helps to decide to Unity 
       container what it should inject(appropriate viewModel to necessary 
       View)*/
}

那么在您的 ViewModel 中,我们应该实现这个接口:

public MenuViewModel:IViewMainWindowViewModel
{}

视图应该注入这个接口:MainWindows.xaml.cs
public partial class MainWindows : UserControl, IContentAView
{
    public MainWindows(IViewMainWindowViewModel viewModel)
    {
        InitializeComponent();
        DataContext = viewModel;            
    }
 }

删除 StartupUri 并重写 App.xaml.cs 中的 OnStartup 方法:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    IUnityContainer container = new UnityContainer();
    container.RegisterType<IViewMainWindowViewModel, MainWindow>();
    container.RegisterType<IViewMainWindowViewModel, MainWindowViewModel >();
    container.Resolve<MainWindow>().Show();
    //Do the same actions for  all views and their viewmodels
}

嘿,你写代码之前看了我的更新吗?我不确定你的IViewMainWindowViewModel是什么意思。 - Mikkel
@Mikkel,你忘记注册视图和它的接口了。 - StepUp
1
@Mikkel 兄弟,就按我展示的方法来做。你的接口 'IMenyViewModel' 不应该有任何方法或命令。它只是视图和视图模型之间的契约,并帮助 Unity 容器决定应该注入什么(将适当的视图模型注入到必要的视图)。 - StepUp
我应该做你告诉我要做的事情...只是我的MainWindow仅实现了空接口,但没有实现UserControl、IContentAView,不知道这是否重要。 - Mikkel
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接