1

I'm really confused about what is supposed to be inside a Module.

When I call RegisterViewWithRegion for many views they are all loaded together during Module initialization... All those views are intended to be hosted inside the same region because they are diferent processes of the same module.

Let-s say that I have a Module named Inventory and it contains a view for Products, a view for Orders, etc. All of them are associated with a region named "MainRegion" and I would like to instantiate those views when user requests them, not when the module gets initialized.

In my mind, the only answer to this enigma is that Prism modules are intended to have (what I call) ONLY ONE process inside, so this way I'll end up with different modules like this:

Inventory.Products.xap

Inventory.Orders.xap

... and so on.

Is that right? Is there any alternative that let me keep those processes together inside One module? and in this case, is this convenient?

Thanks in Advance! Jean Paul

jpmir
  • 101
  • 1
  • 8

3 Answers3

4

Prism makes a distinction between instantiating a view and displaying it. Prism 4 has a new API for displaying regions on demand, but display-on-demand can be done with older versions, as well. Unless your views are resource intensive, I'd suggest loading them at bootstrap-time, then displaying them as requested by the user.

Here are a couple of articles that should help:

Prism 4.0 Display-on-Demand

Display-on-Demand - Older Versions of Prism

David Veeneman
  • 18,912
  • 32
  • 122
  • 187
  • Thanks David!... Yes, my views instantiates a Viewmodel and this VM instantiate a UnitOfWork with several lookup lists and security related objects... That's why I don't like the fact that they get instantiated at module initialization... – jpmir Apr 01 '11 at 21:19
4

Just to add to what @David said, Prism helps u logically separating different modules, and separating each view to its own module is (a) a huge overkill, and (b) a bad architecture.

good architecture is knowing how to divide & conquer the tasks of the application, which means knowing when to divide things, and sometimes even more importantly, when not to divide things.

Elad Katz
  • 7,483
  • 5
  • 35
  • 66
  • 1
    The thing is that One module is not supposed to contain more than 1 view for the same region unless this second view is going to be instantiated from the first one. As far as I understand this concept, a Module is a set of views related with 1 specific function in the system and some child views accesible from their respective parents. Right? – jpmir Apr 05 '11 at 01:48
  • couln't have said it better myself :) – Elad Katz Apr 05 '11 at 10:44
0

Well, I guess I finally understand how it's supposed to work.

In order to set the grounds for this post, let's say that an application Module (not a prism module) is a collection of views (previously named Forms) and procedures related to specific activities on a business process, for example: Sales, Inventory, banking... etc.

Inside each Application module, we will find processes like Sales.Invoices, Sales.Orders, Inventory.Products, Inventory.Stocks, etc.

Now, in prism as @Elad says, create a new project for each process inside inside an Application Module may be a huge overkill, And as @David says, Prism makes a distinction between instantiating a view and displaying it.

Well, to do the right thing (which is listen to these guys), I decided to go like this:

1) Differenciate a Visual Studio project from a Prism Module: It's not really necessary to break Application Modules into different project in your solution, all you need to do is create one project by "Application Module"

2) Create different Module Initializer Classes inside each "Application Module" project, one for each process e.g.:

For Process "A" Inside MyApplicationModule:

      <ModuleExport(GetType(MyApplicationModule.ProcessAInitializer))> _
    Public Class ProcessAInitializer
        Implements IModule

        <Import()> _
        Public Property RegionManager As IRegionManager


    #Region "IModule Implementation"
        Public Sub Initialize() 
                   Implements Microsoft.Practices.Prism.Modularity.IModule.Initialize
            RegionManager.RegisterViewWithRegion(RegionNames.SubMenuView, 
                            GetType(MyApplicationModule.SubMenuViewA))
            RegionManager.RegisterViewWithRegion(RegionNames.ContentRegion,
                            GetType(MyApplicationModule.ContentViewA))
        End Sub
    #End Region
    End Class

For Process "B" Inside MyApplicationModule:

<ModuleExport(GetType(MyApplicationModule.ProcessBInitializer))> _
Public Class ProcessBInitializer
    Implements IModule

    <Import()> _
    Public Property RegionManager As IRegionManager


#Region "IModule Implementation"
    Public Sub Initialize() 
            Implements Microsoft.Practices.Prism.Modularity.IModule.Initialize
        RegionManager.RegisterViewWithRegion(RegionNames.SubMenuView,
                          GetType(MyApplicationModule.SubMenuViewB))
        RegionManager.RegisterViewWithRegion(RegionNames.ContentRegion,
                          GetType(MyApplicationModule.ContentViewB))
    End Sub
#End Region
End Class

3) Once we got this, let's change a little bit how your modulecatalog is being created on your shell project. In my case, I'm using code to add Prism Modules one by one, you could load the Modules Definition from a file but the principle is the same:

Protected Overrides Function CreateModuleCatalog() As 
                          Microsoft.Practices.Prism.Modularity.IModuleCatalog
    Dim objModuleCatalog = New ModuleCatalog
   objModuleCatalog.AddModule(New ModuleInfo() 
                              With {.InitializationMode = InitializationMode.OnDemand,
                                    .Ref = "MyApplicationModule.xap",
                                    .ModuleType = "MyApplicationModule.ProcessAInitializer, MyApplicationModules, Version 1.0.0.0, Culture=neutral, PublicKeyToken=null",
                                    .ModuleName = "ProcessAInitializer"})

   objModuleCatalog.AddModule(New ModuleInfo() 
                              With {.InitializationMode = InitializationMode.OnDemand,
                                    .Ref = "MyApplicationModule.xap",
                                    .ModuleType = "MyApplicationModule.ProcessBInitializer, MyApplicationModule, Version 1.0.0.0, Culture=neutral, PublicKeyToken=null",
                                    .ModuleName = "ProcessBInitializer"})
    Return objModuleCatalog
End Function

Conclusion

This way, Your views will be instantiated only when user request this specific "Business Process", you don't need to split your solution into smaller parts so it take forever compiling and your solution still being "team friendly".

Thank you @David & @Elad

jpmir
  • 101
  • 1
  • 8