I was working on a modular/composite application using Prism and MEF. One of the most issues i encountered, was using the Prism ViewModelLocator to bind the view context to the right view model instance. After googling, I had to write my own convention basing on Prism default convention. the new custom convention allows me to bind view models not necessary having the same namespace as the view namespace. also makes it possible to bind these view models event if are in another separated assembly.
I started by creating an interface named IMvvmTypeLocator :
The interface above has initially 3 methods, i will focus-on and share only the first one (GetViewModelTypeFromViewType(Type viewType)) to acheive my goal.
the 2 other methods are helpful for me to do the same but to locate the view type from a gived view model type or a given view name.
Implement the interface :
I created a class to implement the interface IMvvmTypeLocator, this class has the AggregateCatalog as constructor argument.
Note that we are going to create a custom convention to locate the target view models in all registered assembly catalogs
What the method GetViewModelTypeFromViewType does ?
This method starts by applying the default PRISM convention (GetDefaultViewModelTypeFromViewType method) to locate the target view model, if no view model located, then apply the custom one.
- Get the loaded assemblies from the aggregate catalog:
- All the assemblies added to the aggregate catalog in the BootStrapper.
- Locate all non-abstracte classes inheriting from BindableBase class of PRISM (supposed to be a view models).
- The type name ends with the extension ‘ViewModel’
- If the view type name ends with the extesnion ‘View’:
- Locate the type name without the extension ‘ViewModel’ equals to the view type name without the extension ‘View’.
- If the view type name doesn’t end with the extension ‘View’:
- Locate the type name without the extension ‘ViewModel’ equals the view type name.
If you added the assembly MyAssembly1.dll (contains the view models inside whatever their namespaces) to the assembly catalog. This custom convention will search inside this assembly for the target view model. If your view named MainView or Main: The convention will look for all the non-abstract classes ineheriting from BindableBase class, and named MainViewModel.
Use the custom convention
To use the custom convention, I created a new instance of IMvvmTypeLocator on the application BootStrapper. then i overrided the method ConfigureViewModelLocator.
Create field in the bootstrapper :
Create new instance of the class MvvmTypeLocator once the AggregateCatalog is configured:
Apply the new convention to the ViewModelLocatorProvider:
Note that you are responsible of the view model naming, because this convention will allow the view model locator returning the first found occurence, then ensure that this view model type name is unique.