Taking a deep dive into Prism 6+ library, I find the framework requires a decent learning curve and ceremonies (almost every step of the way), in order to effectively make use the framework.
I am jotting down my notes on the blog so that I can remember, and refer back. However I think others will find it useful too. I will also try and compare to Caliburn Micro wherever I can.
Convention based view-model locator
Starting v5.0, Prism supports conventions to find and auto-wire view and respective view-model. Convention based auto-wire is now the recommended way.
The out of the box convention is basically defined in the static function _defaultViewTypeToViewModelTypeResolver.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static Func<Type, Type> _defaultViewTypeToViewModelTypeResolver = | |
viewType => | |
{ | |
var viewName = viewType.FullName; | |
viewName = viewName.Replace(".Views.", ".ViewModels."); | |
var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName; | |
var suffix = viewName.EndsWith("View") ? "Model" : "ViewModel"; | |
var viewModelName = String.Format(CultureInfo.InvariantCulture, "{0}{1}, {2}", viewName, suffix, viewAssemblyName); | |
return Type.GetType(viewModelName); | |
}; |
The rule is pretty simple
- Prism expects all Views to have a full name with the prefix “.Views.” (mind the dot in the beginning and end)
- The name of the View should end with the literal “View”
Note: Namespace is plural i.e. “Views” and the name of the view is singular “View”. Example: SomeModule.Views.MainView
The static functor then derives the respective view-model name from the view by
- Changing namespace “.Views.” to “.ViewModels.”
- Set “ViewModel” suffix to the class name
Thus a view “SomeModule.Views.MainView” becomes “SomeModule.ViewModels.MainViewModel”.
Prism instantiates the view-model by calling Activator.CreateInstance with full ViewModelName as parameter.
The naming convention allows us to neatly organize our view and view model in their respective folders
Note: Just by using the naming convention, the view and view-model would not automatically wire-up (unlike CM). Prism requires a ceremony here i.e. the View should also be marked with AutoWireViewModel attached property, and set to true
Using the attached property, Prism hooks into the view, instantiates the respective view model, and binds them together via DataContext – see ViewModelLocator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static void Bind(object view, object viewModel) | |
{ | |
FrameworkElement element = view as FrameworkElement; | |
if (element != null) | |
element.DataContext = viewModel; | |
} |
You can override the default static functor via “ViewModelLocationProvider.SetDefaultViewModelFactory” function, and introduce your own convention as you may like.