使用 Prism 7 的 WPF 应用程序:如何使用具有多个具体接口的 VM 注册和导航 类

WPF App using Prism 7: How to Registration and Navigation for a VM using a Interface with Multiple Concrete Classes

我正在使用 Prism 7 创建 WPF 应用程序。在其中一个视图模型中,我试图注入一个名为 IActivityService 的接口。 IActivityService 有多个具体的 classes 但出于问题的目的,TestActivtyService 和 ExerciseActivityService。以下是我如何注册它们:

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
      containerRegistry.Register<IActivityService, TestActivtyService>(InstanceNames.TestActivtyService);
      containerRegistry.Register<IActivityService, ExerciseActivityService>(InstanceNames.ExerciseActivityService);

      containerRegistry.RegisterForNavigation<Shell, ShellViewModel>(ViewNames.Shell);
      containerRegistry.RegisterForNavigation<Home, HomeViewModel>(ViewNames.Home);
      containerRegistry.RegisterForNavigation<ActivityManagement, ActivityManagementViewModel>(ViewNames.TestManagement);
}

ActivityManagementViewModel 有一个利用 IActivityService 的构造函数。

private readonly IActivityService _activityService;

public ActivityManagementViewModel(IRegionManager regionManager, IActivityService activityService)
    : base(regionManager)
{
    this._activityService = activityService;
}

我无法导航到使用 ActivityManagementViewModel 的 ActivityManagement 视图。

private void NavigateToTesting()
{
    //Navigate to ActivityManagement with TestActivtyService injected as IActivityService
    RegionManager.RequestNavigate(RegionNames.MainRegion, ViewNames.ActivityManagement.GetUri());
}

private void NavigateToExercise()
{
    //Navigate to ActivityManagement with ExerciseActivityService injected as IActivityService
    RegionManager.RequestNavigate(RegionNames.MainRegion, ViewNames.ActivityManagement.GetUri());
}

问题

  1. 当我导航到 ActivityManagement 视图时,它总是使用最后注册的具体 class 作为 IActivityService 注入 ActivityManagementViewModel。 为什么会这样?
  2. 如何在运行时使用选择的具体 class 导航到视图?

之所以要这样做是因为视图UI和要求对于接口的每个具体实现都是完全相同的。不同之处在于具体 classes 使用的数据和数据存储库。为每个具体实现重新创建完全相同的视图和视图模型以完全相同的方式显示数据对我来说没有意义。在引入新的具体实现时必须始终添加它们也不是一件好事。

如果我遗漏了什么或者有更好的方法来实现这一点,请教我。

当你在没有命名的情况下统一注册多个具有相同接口的类型时,最后一个类型会覆盖前面的类型。 如果使用命名注册,则只有命名注册和没有默认注册,因此在解析视图模型时会出错。

How do I navigate to the view using the concrete class of choice at runtime?

我会创建一个工厂并注入它,例如:

internal class ActivityServiceFactory : IActivityServiceFactory
{
    public IActivityService Create( ActivityServiceType activityServiceType )
    {
        switch (activityServiceType)
        {
            case ActivityServiceType.Test: return new TestActivtyService();
            case ActivityServiceType.Exercise: return new ExerciseActivityService();
            default: throw new IllegalArgumentException();
        }
    }
}

然后在视图模型中解析activity服务。根据需要调整工厂,例如不同种类 的产品或单体产品。邪恶但合理的地方可能是简单地将容器注入工厂。