【问题标题】:Creating a WPF application with Prism Unity bootstrapper使用 Prism Unity 引导程序创建 WPF 应用程序
【发布时间】:2021-08-20 13:56:26
【问题描述】:

我觉得我看到这个问题问了很多,但是我看到的大多数教程/示例都已经过时了,因为 UnityBootstrapper 类已经过时并且似乎已经被贬值了。我似乎只能找到PrismBootstrapper,它没有实现与UnityBootstrapper 相同的功能。

谁能给我一个如何使用PrismBootstrapper 的例子,或者指出我在尝试从UnityBootstrapper 派生时做错了什么?

我正在尝试遵循本教程: https://www.c-sharpcorner.com/blogs/creating-a-first-wpf-application-using-prism-library-and-mvvm-architectural-patternstep-by-step2

编辑:这是我需要让 MVVM Prism.Unity with Bootstrapper 工作。我不明白如何正确配置 IModuleCatalog 或 RegisterTypes。我还是不太明白 RegisterTypes 是做什么的,或者如何使用我注册的接口。

  1. 我创建了 2 个项目。名为 MRC 和 AlertsLogger 的主项目(WPF 应用程序(.NET Framework))。

  2. 这是我的引导程序的代码。这是设置为在运行时运行而不是打开窗口。

using System;
using System.Windows;
using AlertsLogger.Interfaces;
using MRC.Framework.Core.Data.Connectivity;
using Prism.Ioc;
using Prism.Modularity;
using Prism.Unity;
using Unity;

namespace MRC
{
    [Obsolete]
    public class BootStrapper : PrismBootstrapper
    {

        #region Override Methods
        
        protected override DependencyObject CreateShell()
        {
            return Container.Resolve<Shell>();
        }

       protected override void RegisterTypes(IContainerRegistry containerRegistry)
       {
            containerRegistry.RegisterInstance<IListener>(new Listener());
            containerRegistry.RegisterInstance<IConnectionProvider>(new ConnectionProvider());
            containerRegistry.RegisterInstance<ISettingsProvider>(new SettingsProvider());
       }

        protected override void InitializeShell(DependencyObject shell)
        {
            base.InitializeShell(shell);
            App.Current.MainWindow = (Window)shell;
            App.Current.MainWindow.Show();
        }

        protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
        {
            base.ConfigureModuleCatalog(moduleCatalog);
            Type ModuleLocatorType = typeof(AlertsLogger.ModuleLocators);
            moduleCatalog.AddModule(new Prism.Modularity.ModuleInfo
            {
                ModuleName = ModuleLocatorType.Name,
                ModuleType = ModuleLocatorType.AssemblyQualifiedName
            });
        }
        #endregion
    }
}

  1. 在 AlertsLogger 项目中,我必须创建一个名为 ModuleLocators 的类。
 public class ModuleLocators : IModule
    {
        #region private properties        
        /// <summary>        
        /// Instance of IRegionManager        
        /// </summary>        
        private IRegionManager _regionManager;

        #endregion

        #region Constructor        
        /// <summary>        
        /// parameterized constructor initializes IRegionManager        
        /// </summary>        
        /// <param name="regionManager"></param>        
        public ModuleLocators(IRegionManager regionManager)
        {
            _regionManager = regionManager;
        }
        #endregion

        #region Interface methods        
        /// <summary>      
        /// Initializes Welcome page of your application.      
        /// </summary>      
        /// <param name="containerProvider"></param>      
        public void OnInitialized(IContainerProvider containerProvider)
        {
            _regionManager.RegisterViewWithRegion("Shell", typeof(Views.LoggerDataView));

        }
       

        /// <summary>        
        /// RegisterTypes used to register modules        
        /// </summary>        
        /// <param name="containerRegistry"></param>        
        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
        }
        #endregion
    }

【问题讨论】:

  • 您不想创建自己的容器,而是在RegisterTypes 中使用提供者IContainerRegistry
  • 好的,我对其进行了编辑以将其添加到IContainerRegistry,但我不确定如何使用它。我知道如果我创建一个类,比如说TestClass 并创建一个构造函数public TestClass(Interface InterfaceName){} 它应该通过,但是我需要在该类中创建一个新实例还是应该通过注册来处理实例?
  • 如果你解析TestClass,容器将尝试解析InterfaceName,并在其中放置一个实例,如果它知道要使用哪个实例。它还将负责生命周期管理,例如单例或瞬态实例。您必须为要解析的所有接口注册实现,具体类型会自动解析...但这确实是一个很大的领域,最好阅读一些有关依赖注入和控制反转的书籍...

标签: c# wpf mvvm prism


【解决方案1】:

只要它存在,您就可以使用UnityBootstrapper,而且实际上有充分的理由这样做(想到集成测试)。

如果您不想使用它,您可以让您的 App(在 App.xaml 中)从 PrismApplication 的 Unity 版本(包括UnityBootstrapper(但每个进程仅限于一个实例,这实际上会扼杀 Specflow-testing)。

App.xaml:

<unity:PrismApplication x:Class="WpfApp1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:unity="http://prismlibrary.com/"
             x:ClassModifier="internal" />

App.xaml.cs:

internal partial class App
{
    protected override void RegisterTypes( IContainerRegistry containerRegistry )
    {
        // ...
    }

    protected override Window CreateShell()
    {
        // ...
    }
}

旁注:您不会创建自己的容器实例(至少在 99.9% 的情况下),而是使用作为参数提供给 RegisterTypesIContainerRegistry。它只是所用容器的包装器,所以如果您在切换容器时既没有发现文档也没有发现一致的行为,请不要感到惊讶。好消息是你可以在它上面使用GetContainer扩展方法来获取真正的容器。

【讨论】:

  • 您查看我发送的链接了吗?我之所以问,是因为还有其他功能,例如:Public override void Run(runWithDefaultConfiguration){}只给了我&lt;unity:DialogWindow/&gt;的选项
  • @IShouldKnowThis:那么您在设置方面遇到了什么问题?
  • 好的,我们将使用带有引导程序的 Project1 的 ExampleApplication。在RegisterTypes 中,我会做类似UnityContainer container = new UnityContainer() 的事情,然后我会添加类似container.RegisterInstance&lt;?&gt;(?) 的内容,我不确定里面有什么或它到底在做什么。还是应该注册一个接口的实例?喜欢Public Interface Testing{public string TestInterface{get;set;}}
  • 您不应该在RegisterTypes 中创建容器。您将获得对 IContainerRegistry 的引用,您可以使用它来注册您的类型。
  • 你能给我看一个应该在这两个覆盖中使用的代码示例吗?或者可能给我发一个链接到当前的例子?
猜你喜欢
  • 2012-02-11
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
相关资源
最近更新 更多