RegionManager inheritence

Topics: Prism v2 - Silverlight 2, Prism v2 - WPF 3.5
Mar 22, 2009 at 8:00 PM

I'm looking into inheriting the RegionManager but I ran into a snag.

The CreateRegionManager is not virtual. So when my derived impl is called, the default RegionManager is created and returned.

Not sure how to get around this except changing the source code or copying the complete implementation of RegionManager into my custom class...

Mar 23, 2009 at 8:34 PM


Could you share your specific use case? What are your requirements?

The RegionManager class was not designed be inherited from nor to be an extensible point of Composite Application Library (CAL) because most of the things that you will probably want to do don’t require extending or changing the behavior of this class. As you may know, this class keeps a reference to Regions defined inside views in a collection. So, the code of this class is very generic and should match with the required behavior in most cases.

Anyway, like the documentation says, you can create a custom class that implements the IRegionManager to change the out-of-the-box behavior. As you said, probably, you are going to copy most of the code in the RegionManager class. You can find more information about it in the following article inside the documentation:

·         UI Composition (especially, “Working with Regions” section)


Another way to extend the functionality could be creating an extension method for the current RegionManager class.


Please, let me know if this helps or provide more information about what you are trying to implement, so together can find the best way to do this.


Ezequiel Sculli

Mar 23, 2009 at 9:30 PM
Hi Ezequiel,

Thanx for answering.
My use case is that I want to minimize coupling between the host (shell) and a module, in order to make modules really reusable across multiple hosts/shells. I'm not really using CAL for a composite business app, more as a sort of plugin model. One of the couplings between module and host is the region name. But what if another host defines different regions? So I've created an ILogicalRegionManager interface that derives from the CAL IRegionManager interface. This logical manager accepts RegionHints, an enumeration (flags) that allows a module to specify what it would prefer. I'm still designing this but right now RegionHints include for example, Center, Left, Top, Right and Bottom, which you can combine (but I think I need more, so maybe RegionHints will become a class with placement and other hints...). Its up to Logical Region Manager (and how the hosts initializes its mapping during bootstrapping) how these hints are translated to phyisical regions. When a module hosts public regions it can extend the mapping in the global Logical Region Manager or if the regions are context-specific it can create a new Logical Region Manager and initialize that mapping (similar to how CAL intents to work).

I've already gone ahead and implemented the ILogicalRegionManager with an injection ctor receiving IRegionManager. So I use containment and route all IRegionManager methods to the contained instance. I initially also had designed an ILogicalRegion (derived from IRegion) but dropped that for now, because implementing that and the collection became very ugly, very quickly. Because I intercept all IRegionManager calls I can fix the type returned from the CreateRegionManager function and my problem is solved.

My next challange is creating a CommandManager for the same purpose: de-coupling dependency between modules and how commands are expressed in the UI. So the Module just registers their command with the Command Manager also providing a hint (I would like this to be a toolbar button) but the host decides, or instructs the command manager in such a way that it does as the host wishes. Private Commands used by the Module itself can bypass the CommandManager, but that would not be prefered as that could interrupt the consistency of the UI.
I've created a IUserInteraction service that allow modules to ask the user something, like a message box, but the host decides how that is presented. Instead of modules poping up MessageBoxes left and right, the host might decide that it will integrate this message into the main window (or something else).

Another big nut to crack will be the Module context that I'm planning to build. A module context will contain a module specific Unity Container that contains services specific for the Module. Unresolved services requests should be forwarded up the tree, to the parent container. I've already implemented my IServiceRegistry interface that does the most common RegisterType and RegisterInstance methods and is derived from IServiceLocator (and IServiceProvider) and is based on a Unity container. I've created the IServiceRegistry because I do not want the Unity dependency to leak into every module (I might wanna switch containers for specific hosts).

Anyway, I would suggest you scan the CAL source code for cases like the RegionManager class and make all classes that were not designed for inheritence sealed. Extension methods also crossed my mind but I rejected it because I work totaly interface-based (the unity container is perfect for this). I don't know if its even possible but extending interfaces is not a good idea ;-).
Mar 25, 2009 at 2:55 PM

Regarding the ILogicalRegionManager class, I am not sure what would the RegionHints do exactly on different circumstances. Would it be a good option to use the View Discovery concept for your scenario, and instead of modifying the RegionManager itself, modify the ViewRegistry (or create a completeley new different registry if you'd like) and/or the AutopopualteBehavior behavior?
In this way, instead of pushing views into regions that you don't know that will be available, you just register (configure) views, and then a region behavior will pull out those registered views and push them into existing regions (using the hints you define).

By the way, if going with the ILogicalRegionManager and regarding the CreateRegionManager, this method is only called using the IRegionManager interface when creating new scoped regions. You could then explicitly define the implementation for it:

IRegionManager IRegionManager.CreateRegionManager()
   return new LogicalRegionManager(...);

and in case anyone wants to call it explicitly on the concrete class, define the method using the "new" keyword.
You should suggest making this method virtual in the issue tracker, as this method is here to allow extending the class, so this should be considered a bug.

I hope this helps,
Julian Dominguez

Mar 26, 2009 at 8:29 AM

Hi Julian,

I'm not really modifying the CAL RegionManager, I'm just extending it with more methods on a new interface. So its completely backwards compatible and all CAL principles of working with regions still apply. I'm still very content with my implementation of the LogicalRegionManager based on containment of the original IRegionManager and forwarding/intercepting the calls.

In both view discovery and view injection you have to specify a region name. This hard-coded name, that tighly couples the module to the shell, is what I'm trying to fix (I need my modules to be shell agnostic so they can be reused in different shells).

I'm currently looking into the Region adapters and behaviors and the ViewRegistry to get a feel on how I could use them and when they are created and called etc. There seems to be almost no docs on those subjects. I'm also trying to wrap my head around how to deal with a complex layout similar to visual studio, with mulitple dockable views in combination with multiple instances of views. I've found a blog article that claims to solve the integration of the dock control into CAL but it looked very rough (they derived a specialized region to do coupling to the dock-control, but I believe that is were the adapters are for...) Based on these finding I will decide how to implement the mapping logic in the LogicalViewManager (which is currently a stub and does a RegionHint.ToString() to get to the region name ;-).

Marc Jacobi

Mar 26, 2009 at 2:12 PM
Edited Mar 26, 2009 at 2:12 PM
Hi Marc,
I am glad you found a way to solve it using the current code.
When I meant use the View Discovery concept, I meant not taking the code as is, but extend it or create a new behavior and registry that takes Hints into account, instead of a region name, and the behavior will  know how to translate these hints into the real region name.

It was just a suggestion nevertheless, but you should use what best suits your needs, as there is no right or wrong in these options.

Mar 26, 2009 at 2:28 PM
I'm having some trouble wrapping my head around the whole RegionAdapter/Behavior "thing" and figuring out how they could work for me. But what you say (a RegionHint-based registry and behavior) sounds good. I found the "Create a custom RegionAdapter" section in the CAL docs and that looked simple enough and I think I understand what it is an adapter is supposed to do. But behaviors are still a (dark) gray area. I can see that some of them get registered during bootsrapping and that adapters can also register them, but its a puzzle what part the behavior plays and when it is played. This combined with a complex layout, multiple view, etc. makes my head spin...