FreshMvvm
FreshMvvm copied to clipboard
Feature Request: Provide a way to let user decide which FreshPageModelWrapper used
Based upon Pullrequest #70 and #71
The motivation was that PageModel should be use Page name extension and ViewModel should be use View as name Extension. Because of a typo the ViewModel uses the Page name extension also. #70
Simple replacement of Page to View is not possible because it would be break a lot of application without update the code of the apps. (it make sense, or not) #71
looks to me like a workaround to solve the problem.
My Question (remember i am new on C#):
Why we could not simple use the IoC Pattern here? and let the user the choice to register a own Mapper?
public static IFreshPageModelMapper PageModelMapper { get; set; } = new FreshPageModelMapper();
With IoC ?
public static IFreshPageModelMapper PageModelMapper { get; set; } = FreshIOC.Container.Resolve<IFreshPageModelMapper>();
would work, but requires configuration. i'd expect it to "just work".
and although it does not make much of a difference if things are called view or page, it just makes it easier for users -- even more for users of other frameworks using "convention over configuration".
we won't be the last ones to stumble upon this, so hopefully something will happen about it.. :)
It is not clear in the documentation that you cannot have a naming convention of *ViewModel and *View. After stumbling around a while I realized I needed .Replace ("ViewModel", "View"); and NOT
.Replace ("ViewModel", "Page");
Exactly. I just made a PR to fix this
Any updates on this? I am trying to use the *View and *ViewModel convention in my app and it doesn't seem to be liking it even though the readme says
Note ~~Different to standard naming conventions, FreshMvvm uses Page and PageModel instead of View and ViewModel, this is inline with Xamarin.Forms using Pages~~ Now we can use both the ViewModel naming conventions.
This makes me think that you'd be able to use either, yet it isn't working in my app. when using FreshPageModelResolver.ResolvePageModel<HomepageViewModel>(); it seems to be looking in the .Pages.HomepagePage namespace for the view instead of .Views.HomepageView which is where it is stored....
wat ._.
The FreshPageModelResolver returns a Xamarin.Forms.Page not a View, that is why the default PageModelMapper maps "ViewModel" to "Page" ( see Michael's explanation here: https://github.com/rid00z/FreshMvvm/commit/90aeaa718c44e7d3be385738b155ed9533d74994#r19183606 ).
For my project I am considering making some Pages composable from a number of View widgets, for example there will be a BI style dashboard and this dashboard and other pages will be configurable for content and different levels of interaction. There will be enough presentation logic and/or data/service uniqueness to these View widgets to justify them having their own ViewModel rather than just using the PageModel.
While this approach will introduce performance and usability challenges I have a vested interest in pursuing it.
I will be forking FreshMvvm in order to add in a FreshViewModelResolver which will operate alongside the FreshPageModelResolver. The PageModel + ViewModel Resolver conventions will be PageModel > Page and ViewModel > View respectively.
@MoralCode I got around the namepsace mapping issue with the following custom PageModelMapper, you could add the ViewModel > View mapping you want, although I recommend naming Xamarin Pages and Views as such ( see my comment on adding support for Xamarin.Forms.Views to the framework above ):
( see FreshMvvm 2.1 and 2.2 release announcement for instructions on using a custom PageModelMapper: https://michaelridland.com/xamarin/announcing-freshmvvm-2-1-and-2-2/ )
public class XFreshPageModelMapper : IFreshPageModelMapper
{
public string GetPageTypeName(Type pageModelType)
{
string pageModelTypeName = pageModelType.AssemblyQualifiedName;
// Page Locator.
return GetPageLocation(pageModelTypeName);
}
private string GetPageLocation(string pageModelName)
{
string result = string.Empty;
// Check for presentation namespace folder.
// Presentation > UI Mapping.
if (pageModelName.IndexOf("Presentation", StringComparison.Ordinal) > -1)
{
result = pageModelName.Replace("Presentation", "UI");
} // PL > UI Mapping.
else if (pageModelName.IndexOf("PL.", StringComparison.Ordinal) > -1)
{
// Parse namespace separator to avoid false positives.
result = pageModelName.Replace("PL.", "UI.");
}
// Original FreshPageModelMapper implementation with the confusing ViewModel > Page mapping removed.
result = result.Replace("PageModel", "Page");
return result;
}
}