I am new to Prism and I'd like to know why the PRISM has by default some strange architectural limitations: when we are implementing a new module we should know where its views will appear (actual region names). It's seems to be a bit wrong. I want to build
modular applications with some of independent modules which cann be shown in different places and can be reused by other teams in their projects. I think it would be nice if we can register regions with views somewhere in one place (for ex. in Shell project).
So we can compose different applications based on the same modules as we like. No particular region names should be specified.
Maybe I misunderstand something but that's my point of view for today.
Please correct me if I am worng or give me a piece of advice how this problem could be solved using standard approaches.
Thanks in advance.
Views are actually the reusable components, ideally they are encapsulated and can standalone. Event aggregation and shared ViewModels are methods of sharing state/data between views. Where there are numerous ways to manage your views
one way that I use is to have a shell that has only a MainRegion. Each module holds a
main view that serves as the template/layout/regions for various views the module will use - the module.initialize() routine is then responsible for populating the regions with the various views.
The Module places its main view in the shell's MainRegion - the first view placed in the MainRegion will be the default view. The various module views can be activated which will bring them to the front.
Another approach, from a recent forum message, would be to have your MainRegion have a leftRegion (treeview) and a rightRegion where the left region is a navigation treeview - as you click a node it loads the applicable modules main view into the right region.
PRISMs flexibility gives you a lot of control over your layout.
PRISM is very powerful and extensible - for example, I am creating a Multi-Targeting application using PRISM that allows me to use a single code base for Silverlight, WPF and WinForms (http://multitargeting.CodePlex.com).
TIP: If you understand the MVP and MVVM patterns as well as the concepts of Dependency Injection and Separation of Concerns the QuickStarts won't be such a steep learning curve; if you are not familiar with them, the time invested in doing so will
help a great deal.
If you have a specific layout in mind I trust there are many members in this forum that could provide you ideas/solutions to meeting them.
One of the main concerns when developing composite application is the decoupling of functionality. Splitting an application in different
modules which are not aware of each other is one of the main points of this kind of applications. Each module has its own views, which no one else can know of, as this would highly increase
the coupling in your application.
Imagine Prism did provide a centralized place for
composing the UI (View Injection and View Discovery sections are related in the article), such as the Shell project. Without a lot of analysis, this would require having a reference to each
of the assemblies that contains the views (for example one per module) in your Shell. You would have control of every view in the application in a single place, which is typical for monolithic applications. If this was the case, the application would not be
able to evolve independently, and every new view/functionality would require changing both the new/updated module and the components that manage the registering of views.
As all modules are do not know of the Shell, there has to be a way to locate a view at a particular place in the Shell. By making each module register its own views you are simply saying, “hey, I do not care
whether the module is loaded or not, the rest of the application should work either way”. Also consider that it makes it easier to change the layout of your application or reuse views, simply changing the layout of the Shell/providing a new one will
set up a whole new layout without having to change any of the modules (they care about the region name, not how it is placed in the Shell).
Erwin van der Valk talks about a similar subject in
To sum up:
- You can change the layout of the Shell, or make your views appear in other Shells simply by having a Region Naming convention.
- You do not have to change any of the existing modules to have a new layout.
- Your modules evolve independently, and are easier to maintain are test.
There is a lot more information about this in the Prism documentation:
Please let me know if this helps.
Jun 20, 2011 at 1:12 AM
Edited Jun 20, 2011 at 3:23 PM
I think we all of us got it wrong somehow.
Let me explain what wrong paths I followed by reading junk posts over the internet which all tells you "do it like this do it like so".
- I tried somehow to make my views not aware of shell regions, I wrote a custom view registry/manager system to specify which view goes in what region => WRONG !!! and this was my only agent who knew that.
- I tried to abstract the idea of view to be used in more that one application => WRONG !!!!!. I tried only to use User Controls (generic controls) and not use a specific type of controls (let say the Telerik controls) and put them into regions.Instead
I wrote my custom regions, region adapters etc. and even a generic navigation system (navigating without knowing the region, the view manager resolved that). I just ended up with very limited capabilities and many lines of code written
for nothing. My user controls (views) were added to regions and adapters were responsible to wrap them in containers lets say RadWindows, so I ended up not been able to use all the features of the RadWindow, an I also needed to write attached (to
views) properties to bee able to control let's say the Title of the RadWindow => ALL VERRY VERRY WRONG !!!! (too much noise for nothing).
- And many many more WRONG things which I will tell if someone will ask.
So in conclusion I learn a lot but important is I learned what is WRONG (from my point of view).
Now I want to tell you about my way of doing things with Prism.
- In a prism application the only generic things are the Model (100% generic) and the View Model (generic in some degree and reusable in some degree.), the views are the specific implementation of the application and you can't reuse them in other
applications.You could do it by abstracting the idea of view into a generic layer of objects and publish them from the modules, good luck I will not follow that path because I know I have to write 100000000000000 lines of code (adapters/generic
layer of objects etc...) just to end up with a system which is generic/reusable (nice in theory, maybe I can use it in the future in my coffee maker :))) but also with limited capabilities.
- NEVER BUT NEVER put a View Model in the same assembly where you put your Views (However you can but you lose the view model's reuse ability or let say you pollute the view model's assembly with views).There are always 3 assemblies. 1. The module assembly which
contains the module controller and the views 2. The View Model Assembly 3. The View Model's infrastructure assembly.
- NEVER BUT NEVER wire up interface from the view model (start windows, put views in regions etc), The idea of interaction service or interaction request is so wrong if used from the view model (even is is abstract made with interfaces) and it goes against
of what o view model is (a view model is just an adapter of the model data to be used better in the view).If we wire up interface from the view model then we know about the view layer in the view model (so that violates the following MVVM pattern
rule View -> knows about View Model -> knows about Model)
- Commands ca be used in the view model but again not to wire up interface but to do something with the model (let's say save some data). If you want to wire up interface you can declare a command at the view level and use it there.MVVM is a TOP ->
DOWN 3 level architecture.A level know about it's underneath level and it's peers.I never understood why for God sake they put the view model in the same assembly with the view (I think people who implemented prism got it wrong at that moment).
Commands in the View Model are just methods of the view model with one additional feature availability (CanExecute() .method)
- You can write code in the view's code behind. They say only the view model instantiation is permitted etc ... why ?I an ideal world where you can do everything from xaml why not but till then if it becomes hard to write the view's behavior in xaml you
can just use the code behind.
- Add many many more if someone asks me.
Hope this is right or I got it all wrong :)).
Please let me know if this helps someone and sorry for my bad English (I learned it from movies :), not my native language)