I need your help.
I am considering removing support for navigating to a ViewModel using INavigationService.NavigateAsync<TViewModel>(). We are making changes to how registration works and in order to continue to support this, we would need to add new extension methods that would be used specifically for navigating using ViewModels.
I was thinking of calling the method Conatiner.RegisterTypeForViewModelNavigation<TView, TViewModel>(). Only then would NavigateAsync<TViewModel> work.
So should we keep it and add the new extension methods to support it, or remove it completely?
If we do keep it, should we remove the method NavigateAsync<TViewModel> signature off of the INavigationService interface and just make it an extension method too?
Well I think you know my opinion. Navigating to ViewModel's is just a bad practice. I'd rather see someone have to jump through hoops to do things poorly than to encourage it.
I completely agree with you, and I even tell people not to do that. Especially when you start getting into modules and navigating between them. I think Prism can be opinionated in this. I can provide a sample on how to write the extension methods so devs that want to can, but they have to purposely opt-in
Umm... Why remove this from the API? What's the motivation and benefit?
Are these developers using this pattern?
@kdawg1406 the motivation is two fold. One is to keep the current navigation consistent and to eliminate any confusion between how NavigateAsync("VIewName") and NavigateAsync<TViewModel>() works in combination with the registration methods RegisterTypeForNavigation<TView>("ViewName") and RegisterTypeForNavigation<TView, TViewModel>. This has been a source of confusion a number of times.
The other is that this coupling is discouraged and this type of navigation is not present in any other Prism platform (back to consistency).
NavigateAsync<TViewModel> was added early on before the code base really matured, and now it is becoming clear that it should not be there.
@brianlagunas In Prism.WPF there is a "View Model-first" approach to navigation. It does not use view model locator. I used it to great benefit in testing. Will there be something analogous on other platforms? (I new very little about other platforms, just curious.)
@dvorn yes, and no. There was nothing specific in Prism tat allowed you to navigate to a ViewModel similar to NavigateAsync<TViewModel>, but Prism for WPF is so flexible you essentially registered your VM with a name, and then gave it a key. But you still had to navigate via the key.
I recommend pinging the XAML Disciples Google Group. I think there is a ViewModel first camp out there.
Would this change break the ViewModel first developers?
@kdawg1406 There is no real ViewModel first in Xamarin.Forms. Essentially you are only using the ViewModel.GetType().FullName as the navigation key, but you are always navigating via a Page
@kdawg1406 to your point, the concept of navigating via ViewModels is very common, and to keep support for it would only require the addition of 3 new extension methods for registering the Views/VM's for ViewModel based navigation. Essentially 6 lines of code, so it's not a big deal to keep it. The only requirement would be a retraining on the registration for this type of navigation.
So instead of using the standard
Container.RegsiterTypeForNavigation<TVIew, TViewModel>()
You would use
Container.RegisterTypeForViewMOdelNavigation<TView, TViewModel>()
Maybe that's not a big deal.
API looks clean, discoverable, and lets developers author their applications they way they want.
Win-win.
I like that the method is more discrete. Much clearer that its intent is for view model based navigation.
To be fair here I would say if people are really using it currently, then the appropriate thing to do is to make the extensions obsolete and remove them in a later release.
@dansiegel well, the problem with that is we are fixing #666 to behave as expected and eliminate the current navigation registration confusion, which essentially breaks the current NavigatAsync<TviewModel>.
So we can keep it, but if we do we need to provide new extension methods that allow it to be used. Otherwise, it will be useless and unusable in its current state.
@brianlagunas we do a lot of multiple-shell work in prism and have tabs linked via messaging and Eventing. I never navigate to a ViewModel - that just seems wrong and laden with all kinds of badness. So I have no need for it; PRISM has a long and valued legacy in providing solid guidance; I would not like to see additional work to the API w.r.t. ViewModel navigation. I do think its time to consider Design Patterns and Idioms like Reactive Extensions' Hot Observables combined with the Repository Pattern in conjunction to navigation in general.
@brianlagunas like I said before I don't care for it and am all for it being removed... I think I've been fairly outspoken on my dislike of the pattern in general. It doesn't seem to have much traction for usage, but if it did then making it obsolete would be the way to go. Of course nothing says obsolete like it doesn't work right 馃槈
Here are three limitations of ViewModel based Navigation:
These are three more reasons in favor of removing the ability to navigate via ViewModels. It's limited and inconsistent with the standard navigation pattern.
One option would be to remove the NavigateAsync<TVIewModel> from the API and provide a GIST of the extension methods that a developer could add to their project if they wanted t support it.
https://gist.github.com/brianlagunas/40b8a7d1e25ccc64623b19f11d758171
I have a fairly successful Prism.WPF application which utilizes viewmodel-first approach. I think some day I will need to port it to UWP and/or Xamarin.
Remember, MVVM is about testing decoupled view models. In my application I am able to do _acceptance tests_ using view model without actual views (some mock views are provided, though). No viewmodel locator, but datatemplates in the views. The tests cover complete user scenarios: from program start to program termination.
What are my options with new Prism on UWP and Xamarin?
I do not care about a particular form of NavigateAsync with templated view model, in WPF I used strings anyway. But seemingly the solution for navigation with view models just boils down to viewmodel locator which requires views anyway.
@dvorn Although your question is off topic, there is no ViewModel first navigation in Xamarin.Forms. It's not possible. Navigation is Page based. Doesn't matter though, because you still navigate with strings/uri in Prism for XF so nothing changes conceptually wise.
@brianlagunas I'm in favor of the change because it would be much clearer that it's not the preferred way of navigating. I started using view model navigation just to make refactoring easier but ended up wasting heaps of time trying to figure out how to do exactly the limitations you listed above. It wasn't clear they weren't available with view model navigation.
Thanks for all the feedback. I have decided to remove it, but I will provide a GIST of the extension methods a developer could use in their app in order to add this capability as an opt-in feature.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.