Prism / MEF: How to RegisterViewWithRegion Without Hard-Coding the Region Name Prism / MEF: How to RegisterViewWithRegion Without Hard-Coding the Region Name wpf wpf

Prism / MEF: How to RegisterViewWithRegion Without Hard-Coding the Region Name


As Meleak already mentioned in his comment: Use a static class

namespace Infrastructure{    public static class RegionNames    {        public const string MainRegion = "MainRegion";    }}

In your xaml code you can use the region name as follows:

<UserControl     xmlns:Inf="clr-namespace:Infrastructure;assembly=Infrastructure"    xmlns:Regions="clr-namespace:Microsoft.Practices.Prism.Regions;assembly=Microsoft.Practices.Prism">    <ContentControl Regions:RegionManager.RegionName="{x:Static Inf:RegionNames.MainRegion}"/></UserControl>


I got it. Turns out I was wrong on one point, and I apologize for that. The parent application's .config settings ARE available at the Module class definition level. One must add the correct references and make the correct Imports (or using) entries. I must have been napping at the keyboard.

In the host application's app.config, add configSection definitions. Here I define sections for two modules:

<configSections>    <sectionGroup name="Modules">        <section name="SearchModule" type="System.Configuration.NameValueSectionHandler" />        <section name="HeaderModule" type="System.Configuration.NameValueSectionHandler"/>    </sectionGroup>   ...</configSections>

In the host application's app.config, add a Modules section, and a subsection for each module:

<Modules>    <SearchModule>        <add key="Region" value="SearchRegion"/>    </SearchModule>    <HeaderModule>        <add key="Region" value="HeaderRegion"/>    </HeaderModule></Modules>

In the Module project, add a reference to System.Configuration.dll. Add "Imports" (VB) or "using" (C#) for System.Collections.Specialized and System.Configuration:

VB:Imports System.Collections.SpecializedImports System.ConfigurationC#:using System.Collections.Specialized;using System.Configuration;

In the Initialize method of the Module's Class definition file:

VB:    Public Sub Initialize() Implements Microsoft.Practices.Prism.Modularity.IModule.Initialize        Dim settings As NameValueCollection = CType(ConfigurationManager.GetSection("Modules/SearchModule"), NameValueCollection)        MyRegionManager.RegisterViewWithRegion(settings("Region"), GetType(SearchModuleView))    End SubC#:    public void Initialize() : Microsoft.Practices.Prism.Modularity.IModule.Initialize    {        (NameValueCollection)settings = (NameValueCollection)ConfigurationManager.GetSection("Modules/SearchModule");        MyRegionManager.RegisterViewWithRegion(settings["Region"], typeof(SearchModuleView));    }

This, then, registers the View with a Region from entries made in the Host application's app.config. This means one module can be built for multiple host applications, and it can be inserted in a Region of any name in the Host. No need to make changes in compiled code, or to make a separate RegionNames class for each application.

Our application is also built using MVVM architecture. We define the View-Models in the Host application, and expose them to the modules by names defined the app.config using RegionContext or EventAggregator. This now completely decouples the modules from the application, and makes the modules totally reusable in different applications without modification.

Thanks for the input, and I hope this helps someone else in the future.