tags:

views:

193

answers:

3

I have an app that has several modules that have completely different functionality and I'm trying to figure out the best way to implement this using prism.

To try and better explain, I'll try to use Northwind as an example. I have 3 modules, orders, customers & employees.

The customer module will allow you to do anything pertaining to a customer. Add, remove and edit. I'm going to use scope regions for the main view in the customer module to handle all the different views I need to show here.

In the scenario above, I only want to load a module when a user wants to work with say a customer, order or employee.

You have these modules laid out and realize that you need to be able to show Orders for customer or sales people which are obviously employees.

What would you do here in this scenario as you wouldn't want to create an entirely new modules for say employeeOrders and customerOrders and you wouldn't want to duplicate any order related code.

I'm starting to wonder if it's feasible to think about building a composite application using prism if you're building an app like Outlook, but for a LOB business app, I've yet to find a good sample of how to do this and not break some of the principles of MVVM and definitions of Prism in order to do so.

I'm just 3 weeks into Prism and still learning but this is the biggest issue I'm running into.

Any thoughts?

A: 

You should be using the Event Aggregator for these types of communication scenarios. Essentially, you want a module to provide functionality but also expose events that can be invoked from other modules. You can also register a service in the Unity container. For example:

public interface ICustomerOrderInvoker 
{
    void DisplayCustomerOrdersInRegion(string customerId, string regionName);
}

These techniques are somewhat orthogonal to MVVM. Your event handler can create a view/viewmodel pair and insert them into a region. Or your event handler can create a UserControl with all functionality implemented in code behind and adds it to a region. The beauty of the composite UI is that your modules can use MVVM and another team's modules can use straight forward user controls or MVP or MVC or anything really; the point is that all the modules are composed into one application regardless of how they are implemented because they use the patterns established in Prism like regions, events, etc.

In your particular case:

You have these modules laid out and realize that you need to be able to show Orders for customer or sales people which are obviously employees.

Your Order module will certainly be aware of the concept of a customer id since the Order entity is associated with a customer. The Order module should expose an CompositePresentationEvent that displays a view that has all the orders for a particular customer id.

The point of Prism is to create logically separate and loosely coupled pieces of functionality. This does not mean that the modules do not communicate with each other, but rather that the communication happens in a limited and loosely coupled manner. You can certainly write LOB applications using this pattern and MVVM; many of us have been for years now. :)

siz
A: 

Thanks Siz. I get modules and EventAggregator etc. I have all that work. I must have done a poor job in asking my question.

I've thought about it since my original post and I'll try to be more clear.

What I'm looking for is a way to dynamically change regions on the shell. I think coming up with dynamic templates for the shell may describe better what I'm looking to do. There is a sample project called LayoutManager that looks to do what I'm describing but there is a lot of plumbing and reliance on config files which wouldn't seem to be ideal for silverlight. (I'm working in WPF but whatever I do I like to make sure I can do the same thing in Silverlight.)

So to try and give a scenario. (It's overly simplified and I know I could use generic region names for most of this scenario but I'm trying to get a point across.)

I have my shell and when the app loads there is a Customer Region & an Order Region. On load, customers load and when a customer is selected, the order region is populated appropriately.

Now in the menu, a user selects Employee. Now I want an employee region, a order region and benefits region to be available in the shell.

Also, let's say this app is has offline capabilities and stores everything locally. I need to add a "synch" manager and when the user selects synch manager, I want a Navigate Region & a Content region to work with.

Looking at LayoutManager and not worrying about having to recompile if I need to make changes, I'm thinking I need to create UserControls to use as templates and place the appropriate regions I need. Then have Global Commands using the EventAggregator as you mention. When an event is fired that requires, my Shell ViewModel or whatever, changes the template it's using.

I have ideas of what may need to be done with the regionmanager and possibly use of scoped regions to get all of this to work.

This is a pretty common scenario for the types of LOB apps I see and work with. I'm hoping somebody out there has a sample or knows of documentation of where this has been attempted.

frosty
A: 

Hi there,

Im working on a similar problem (and am new to Prism too), as yet don't have a solution. I think when using Prism its tempting to use the framework as the reference implementation intends, but it doesn't need to be so.

Prism should (when used correctly) facilitate software development, not hinder it. So don't get too stuck in the idea that any implementation must meet strict decoupled refactorised super patternised standards!

What I am doing/intending to do is create a MainModule, which has in it much of my core functionality, including a MainView/MainViewModel user control. The Shell then has one region "Main" and on MainModule load the MainView is injected into it as per standard prism usage.

I'm using a Docking Manager from Telerik (compatible with Silverlight and WPF) on the MainView and have implemented a class IDockingManager / DockingManager class in Infrastructure which is registered with Unity as a singleton (ContainerControlledLifetimeManager) in the bootstrapper.

Anywhere in my app I can get the IDockingManager instance and inject a view by calling IDockingManager.DockView(IView view, DockingParameters args). The DockingParameters can contain information such as where to dock (Left, right, top, bottom, tabbed document) and also the parent container to dock in.

This is the part I've not got to yet - I can dock left/right/top/bottom on the main view but I want to implement an attached property or something on my child views registering them as a DockSite when docked. So for instance I could dock a Treeview on the left and dock underneath that a listview by using the Treeview name as parent DockSite and DockBottom as the side.

Hope that makes sense, I've rambled without really explaining too well. Basically what Im saying is Im not using regions at all (except to inject the MainView) in this application and have created a class to handle view injection into dockable containers. It's not strictly Prism but Prism is there to make my life easier, not the other way around ;)

andrewb