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

使用Prism 7的WPF应用程序:如何使用具有多个具体类的接口注册和导航VM,wpf,dependency-injection,prism,unity-container,prism-7,Wpf,Dependency Injection,Prism,Unity Container,Prism 7,我正在使用Prism 7创建一个WPF应用程序。在其中一个视图模型中,我试图注入一个名为IActivityService的接口。IActivityService有多个具体类,但出于问题的目的,TestActivityService和ExerciseActivityService。以下是我如何让他们注册的: protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerReg

我正在使用Prism 7创建一个WPF应用程序。在其中一个视图模型中,我试图注入一个名为IActivityService的接口。IActivityService有多个具体类,但出于问题的目的,TestActivityService和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的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());
}
问题

  • 当我导航到ActivityManagement视图时,它总是使用最后一个注册的具体类作为IActivityService注入ActivityManagementViewModel为什么会发生这种情况?
  • 如何在运行时使用所选的具体类导航到视图?
  • 我之所以要这样做,是因为视图UI和需求对于接口的每个具体实现都是完全相同的。区别在于具体类使用的数据和数据存储库。对于我来说,为每个具体实现重新创建相同的精确视图和视图模型来以相同的精确方式显示数据是没有意义的。在引入新的具体实现时,总是必须添加它们也是不好的


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

    当您使用unity在同一界面上注册多个类型而不命名时,最后一个类型将通过覆盖以前的类型而获胜。 如果使用命名注册,则只有命名注册而没有默认注册,因此在解析视图模型时会出现错误

    如何在运行时使用所选的具体类导航到视图

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

    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();
            }
        }
    }
    
    然后在视图模型中解析活动服务。根据需要调整工厂,例如不同种类的产品或单一产品。在这里,邪恶但合理的做法可能是简单地将容器注入工厂

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