We have a product which acts as a base framework for other applications/teams.
I am declaring type mappings through unity configuration. On the other hand, every configured module has its IModule implementation in which we map a view with predefined region.
However, to achieve this, every other 'module' project team has to write its IModule implementation and do 'region mapping/registration' themselves in the code.
Is it somehow possible for every module to tell my base product that it wants to register X, Y, Z types/instances through unity "configuration"? My base framework will resolve types/instances and do appropriate mappings. It will allow module teams to focus just on their WPF business views instead of implementing IModule etc.
At present, type mapping is possible in unity but I cannot associate registration with the Prism module. Further, it's not possible to map a resolved type with the predefined region.
E.g. In our application Shell we have a region named 'BusinessRegion'. We have an interface called IBusinessView. Every module will have several business views. Depending on module & its workflow, we have to navigate from one business view to another. However, at present I cannot know which business view belongs to which module.
The same question is already answered in the following CodePlex forum site:
Can we do WPF view-region mapping & interface-type mappings in the configuration?
As commented at CodePlex's, there wouldn't be possible to know which View belongs to each Module after they are initialized. Views and components get registered in the Container and Regions, loosing any dependency reference with the Module.
Regards.
Related
I have developed a WPF application using Prism and Unity frameworks and I have some concerns regarding the following whether I have implemented them correctly or not.
Abstract classes / Interfaces - I have organized interfaces for all the layers in one assembly and then referenced it in the respective library for implementation. Now, the referenced library has access to all the non required interfaces of other layers. For e.g. the service layer has access to UI interfaces. Is this the proper implementation in terms of clear separation or should I split it into multiple assemblies.
View Model dependencies - I used EventAggregator mostly to communicate between view models. In some cases, I am passing the instance of other view models directly in the constructor and resolving it using DI container. I want to omit the direct view model dependency by introducing the interface to achieve clear separation. How can I organize the interface for view models into a separate assembly in such a way that the other developers could understand.To avoid creating multiple UI projects, I created only one single assembly and logically separated them into folders.
Abstract Module Class - Instead of specifying all the dependencies in bootstrapper.cs file, I factored them in respective module. Most of my class lib projects has references to Prism libraries. Thus, UI specific namespaces are added to non UI related projects. Is there any better approach to achieve this ?
Abstract classes / Interfaces
I'd go for exactly as many "interface-assemblies" as necessary, having too many of them hurts. Example: if you need to prevent layer 1 from potentially communicating with layer 3, put the layer 1-to-layer 2-interfaces in one assembly and those for layer 2-to-layer 3 in another one.
View Model dependencies
Normally, you shouldn't need to pass view models around at all. Pass around the data (a.k.a. model), the view models themselves don't hold any data that's either unavailable elsewhere or valuable to anyone but the view bound to the view model.
Abstract Module Class
Your prism application references prism... so what? As long as only the IModule implementations receive the IUnityContainer I wouldn't care at all. If someone needs to publish an event, he get's the IEventAggregator... That's an interface already, and you can inject a mock in your tests, so no need for further abstraction.
Is there a way to create a product (Software) divided in modules?
What I mean is for example create an application using WPF that is divided in 3 modules (in the future they may be more) Main Module, Module 1, Module 2
Each module could be a standalone solution. Each of them with presentation, Business and Data access layers.
From the Main Module when a button is clicked, it will call any other module for example module 1 but the UI of the module should be seen like if it were from the main Module.
I have manage to use MEF to separate project building but I don now how to use MEF with WPF
Any Starting point or suggestion?
Putting your business and data access layers in a MEF module is fairly straightforward and accomplished as you would for any other project, the trick with WPF is adding the view resources. That can be done by putting them in a ResourceDictionary decorated with the Export attribute and merged into the global dictionary, as shown in the answer to "How to provide XAML resources from MEF components".
Can we have Unity configuration in file other than app.config file of the application? If yes, how to do it?
Can we combine unity configuration spread across multiple files?
How to define Unity configuration in the XAML file? (PRISM modules can be configured in XAML.)
Is it possible to have custom implementation of the Microsoft.Practices.Unity.Configuration.UnityConfigurationSection configuration reader class?
We are developing a WPF application which should allow other developers (working on various ares of the enterprise app) to register their XAML views (user controls) with our application. And depending on the functionality being used, our product will navigate user to the appropriate form/view. E.g. On click of the "Home" button, user would be navigated to the "Dashboard". But Dashboard may or may not be developed by the core product.
I am using Prism 4.1.
I believe that pretty much everything you need is explained in the following section of Unity's documentation:
Using Design-Time Configuration
It describes how to load one or several "configurations" into a Unity container from the default configuration file or from several other independent files.
Based on this, I believe you should be able to have a configuration file in each of your modules and load them manually in the Initialize method (or the module classes' constructors). If not, you can always register the corresponding type mappings programatically in the modules too.
I have developed a Microsoft Prism 4.0 application and I am struggling to understand how to make the user application setting functionality available to modules.
e.g. a Properties.Settings.Default.MyProperty.
I can define a simple class that gets populated via the bootloader (which does have a handle to the properties) and inject that into the modules but If I want to save a change of property, I need believe I need a handle to the Properties.Settings context which is not available to my modules (which are simple class libraries).
Your scenario sounds like the perfect reason to use a "Service" class. Create an interface and class called IUserSettingsService and UserSettingsService that has the information (or can load and save it from where it is stored).
Read Chapter 3 of the Prism 4.0 help file, Managing Dependencies Between Components, Registering Types with (either Unity or MEF, depending on what you are using as your DI Container).
Then, in your ViewModel that needs the user settings, locate and use your service. In MEF, it is as simple as adding a property of type IUserSettingsService with an [Import] attribute, or using [ImportingConstructor] and having a parameter of type IUserSettingsService. With Unity, you access the service through the container. See Chapter 10 of the Prism help file - Advanced MVVM Scenarios.
Added after comment discussion:
Because you need your service to be in the context of your main application, you can implement your service class there. Create the interface for your service in a shared library that can be used by both the main project and your modules. Finally, load the service in the bootloader class instead of in a module.
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?
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. :)
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 ;)