-1

I feel I have seen this question asked a lot, but most of the tutorials/examples I have seen are outdated as the UnityBootstrapper class is obsolete and seems to be depreciated. I can only seem to find PrismBootstrapper which does not implement the same features as UnityBootstrapper.

Can someone give me an example of how to use PrismBootstrapper or maybe point out what I am doing wrong with trying to derive from the UnityBootstrapper?

I am trying to following this tutorial: https://www.c-sharpcorner.com/blogs/creating-a-first-wpf-application-using-prism-library-and-mvvm-architectural-patternstep-by-step2

EDIT: This is what I needed to get the MVVM Prism.Unity with Bootstrapper to work. I didn't understand how to configure the IModuleCatalog or RegisterTypes properly. I still don't quite understand what RegisterTypes does or how to use the Interfaces I have registered.

  1. I Created 2 projects. The Main Project (WPF app (.NET Framework)) called MRC and AlertsLogger.

  2. Here is the code for my bootstrapper. This is setup to run at runtime instead of opening to a window.

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. In the AlertsLogger project I had to create a class called 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
    }
  • You don't want to create your own container, instead use the provider `IContainerRegistry` in `RegisterTypes`. – Haukinger Jun 04 '21 at 06:44
  • Okay, I edited it to add it to `IContainerRegistry`, but I am not sure how to use that. I know if I create a class, let's say `TestClass` and create a constructor `public TestClass(Interface InterfaceName){}` that it should go through, but do I need to create a new instance in that class or is that supposed to be taken care of with registering the instance? – IShouldKnowThis Jun 04 '21 at 14:03
  • If you resolve `TestClass`, the container will try to resolve `InterfaceName` and put an instance in there, if it knows which instance to use. It will also take care of lifetime management, e.g. singletons or transient instances. You have to register implementations for all interfaces you want to resolve, concrete types are resolved automatically... but this is really a large field, better you read a few books about dependency injection and inversion of control... – Haukinger Jun 04 '21 at 14:32

1 Answers1

1

As long as it's there, you can use the UnityBootstrapper, and there are actually good reasons to do so (integration testing comes to mind).

If you don't want to use it, you can make your App (in App.xaml) derive from the Unity-version (include the ) of PrismApplication to get more or less the same features as the UnityBootstrapper (but restricted to only one instance per process, which effectively kills 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()
    {
        // ...
    }
}

Side-note: you don't create your own container instance (99,9% of the time, at least), instead use the IContainerRegistry that's provided as a parameter to RegisterTypes. It's just a wrapper around the container used, so don't be surprised if you find neither documentation nor consistent behaviour when switching containers, though. Good news is that you can use the GetContainer extension method on it to get the real container.

Haukinger
  • 10,420
  • 2
  • 15
  • 28
  • Did you check the link I sent? I ask because there are other functions like: `Public override void Run(runWithDefaultConfiguration){}` I am also not completely sure how to setup the bootstrapper using just the `CreateShell` and `RegisterTypes` Also, I tried to setup the way you have it and utilizing the `xmlns:unity="http://prismlibrary.com/"` only gives me an option for `` – IShouldKnowThis Jun 02 '21 at 12:47
  • @IShouldKnowThis: So what are you having trouble setting up exactly? – mm8 Jun 02 '21 at 13:25
  • Okay for this we will use, ExampleApplication for Project1 with the bootstrapper. In the `RegisterTypes` I would do something like `UnityContainer container = new UnityContainer()` Then I would add something like `container.RegisterInstance>(?)` I am not sure what goes in there or what exactly that is doing. or is it supposed to register an instance of an Interface? like `Public Interface Testing{public string TestInterface{get;set;}}` – IShouldKnowThis Jun 02 '21 at 13:36
  • 1
    You are not supposed to create a container in `RegisterTypes`. You're getting a reference to a `IContainerRegistry` that you can use to register your types. – mm8 Jun 02 '21 at 14:02
  • Could you show me an example of the code that should go in both of those overrides? or possibly send me a link to something that is a current example? – IShouldKnowThis Jun 02 '21 at 15:13
  • @IShouldKnowThis have a look at the base class, there's a ton of overrides. More or less the same as in the bootstrapper... the quoted two are just the ones you _have_ to override (because they're `abstract`), but there are more :-) also, have a look at this answer which deals with the same topic https://stackoverflow.com/a/47910554/5758420 – Haukinger Jun 03 '21 at 14:57