Prism / MEF: how to register a Region without hard-coding a region name

We are creating a WPF Prism application. We have different developers working on various module projects, and several modules are introduced into the main application shell. The main application is a separate project. We also want to be able to use modules in different applications. We do not want to name regions with the same name in each application.

For example, let's say we have a module that will be used in two different applications. In one application, its developer can name the area of ​​the module "DetailsRegion", and in another, its developer can name it "ResultsRegion".

Each example I can find registers a view with a region by hard-coding the region name in the module class definition:

myRegionManager.RegisterViewWithRegion("RegionNameHere", GetType(ModuleViewType)) 

What I want to do is put the region name in the app.config application file of the main application and pass that name to the module. Something like that:

In the main application of the app.config shell:

 <Modules> <SearchModule> <add key="RegionName" value="SearchRegion" /> </SearchModule> </Modules> 

And in the module class file:

 Dim settings As NameValueCollection = CType(ConfigurationManager.GetSection("Modules/SearchModule"), NameValueCollection) Dim regionName as string = settings("RegionName") myRegionManager.RegisterViewWithRegion(regionName, GetType(SearchModuleType) 

In a sense, this would be the last step to completely separate the modules from the shell and from each other.

This works great in module views . But I cannot do this in the class definition file, since the ConfigurationManager is not available at this level.

I can do this by specifying the region name in the ApplicatonSettings section of the app.config module of the module. But this defeats the goal of storing the module in one place for loading by multiple applications. It really should be in the app.config of the main application.

Is there a way to register a View module with an area without hard coding the region name in the code? We try our best NOT to record anything. Is it really necessary here?

+6
source share
2 answers

As Meleik 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> 
+5
source

I understood. It turns out I was wrong at one point, and I apologize for that. Parent application .config options are available at the module class definition level. You need to add the correct links and enter the correct import (or use) records. I must be taking a nap on the keyboard.

In the app.config application application application, 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 app.config application of the application host, add the "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 Import (VB) or Usage (C #) for System.Collections.Specialized and System.Configuration:

 VB: Imports System.Collections.Specialized Imports System.Configuration C#: using System.Collections.Specialized; using System.Configuration; 

In the Initialize method of the module 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 Sub C#: 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 the region from the entries made in the app.config application. This means that a single module can be created for several host applications and can be inserted into the scope of any name in the Host. There is no need to make changes to the compiled code or create a separate RegionNames class for each application.

Our application is also built using the MVVM architecture. We define View-Models in the Host application and place them into modules by the names that define app.config using RegionContext or EventAggregator. This now completely separates the modules from the application and makes the modules completely reusable in different applications without changes.

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

+2
source

Source: https://habr.com/ru/post/897264/


All Articles