Prism: [XF] Should we automatically set AutowireViewModel?

Created on 15 Jul 2016  路  22Comments  路  Source: PrismLibrary/Prism

Currently you must specifically set the ViewModelLocator.AutowireViewModel attached property in your Pages. We can technically do this automatically in the navigation service right after we create the page. This would remove the extra step of having to manually add the namespace and attached property to your views. Although, the Prism template pack has this in all of it's item templates.

This would of course mean that if you do not wish to automatically attached the ViewModel, then you would have to "opt-out" by setting the AutowireViewModel = false.

Do you think this would be too much "magic"? Maybe not intuitive to have to opt-out if you don't want it?

Thoughts?

XF enhancement help wanted

Most helpful comment

By the way, I am leaning towards adding this feature since it really is core to the guidance Prism for XF provides. I need to decide by next week as I plan on releasing Prism 6.2 as stable :)

All 22 comments

Why would you do it for XF and not the other platforms?

It's in the item templates and in de documentation. People using Prism _should_ know it's necessary and keeping it explicit reminds them of this coupling. Doing this in the background will possibly make it more obscure for new users. And the opt-out is not intuitive indeed. My 2 cents.

Don't do it automatically, maybe it can break current codebases and generate a lot of confusions.

With resharper you only need to type ViewModelLocator. then ALT+Enter, Enter for the namespace inculde. This is in my little finger :)

I personally don't know why it's needed... if you request to navigate to a view, it's because you expect it and with a view model. The whole point of the mvvm/ prism . I personally spent over an hour trying to figure out why my view didn't have a vm when I was learning it. I know now, and get it... but think in this pattern, it's assumed to auto wire, and maybe an option to disable autowire at the view attached property is a good option. Or even a global flag to require the attach property, but off by default where you don't require the attached property.

I am still new for the framework, so maybe there is something I don't understand yet on why it's a better practice to require the extra line in the xaml. In today's code, less is more ;). Just my .02c

(sorry for my bad english) Personally, I like the idea. I am using Prism because I want it to do things for me and I think that to not want the automatic wiring of the viewmodel is an exception on a Prism app. I think it should set all the default, expected things so although I think no one should be rewarded for not reading the documentation - we do not punish who does not.

Personally I like when things are elegant and leaving people wondering how you did it. That said I would rather that this be controlled by a global property so that you can choose the paradigm you feel makes more sense for your project. Explicitly opting into, or opting out of the AutowireViewModel.

I would also say that @TWhidden makes a good point, that the whole point of Prism is to use an MVVM approach, which makes a pretty convincing argument to me that defaulting to automatically inject the AutowireViewModel=true would tend to provide an overall enhancing effect. As for the concern that @totht91 brings up about it potentially breaking existing apps, I think that having this controlled by another property so you can turn it on/off globally should make it a low impact item.

@bartlannoeye The real motivation behind this is that in Prism for XF, AutowireViewModel is required in order to get the INavigationService injected into the VM. This is because in XF, navigation is based on the specific Page instance, so we must have an instance based nav service. Besides this, it really is extremely rare that you would not want a VM for a Page.

This change would be considered a breaking change, and a very difficult to debug change if you by chance have a Page that is not using AutowireViewModel. Though honestly, I'm not sure how prominent that scenario would be. It is also inconsistent with WPF and UWP (for now).

I guess the big question is what is the benefit of doing it automatically vs. requiring the attached property? Is it worth the change? Does it make it easier to use Prism for XF, or is it a source for more problems?

I'm really on the fence on this one.

I think this is worth to be set automatically, and sooner the best for the project, it has to be an opt out option, and in theory it mustn't broke any current project because in existing projects if it has been set to true that will be the default behavior anyway, and I also think that the view that is not attached to a view model is an edge case.

Maybe the other option that is left is to use an global option to do it and do the automatically thing an opt in, with this option you have something to measure the feedback of people about this and test if there is not anything broken for anyone, and in the future maybe set to true by default.

I think that any action about this will be more options for the project and ultimately more flexibility for the developer, and I'm sure that everyone has in some point forgotten about this and lost theirs time trying to figure out what is happening... that is my 2c

If the intent is to not have to do this for every page, developers can subclass the SessionStateAwarePage class (using UWP as an example) and set this in the constructor.
If the XF Prism project feels the need to always set this for all of its pages, can't it do the same?

I'm personally against setting this automatically in the NavigationService because of the fact that it's an unnecessary breaking change and does make it difficult to understand what's happening.

Sorta... maybe for some. I haven't seen the previous XF Prism lib, and I am only building myself with the previews... but between versions, there are is always an expectation that something could be broken (to better library). And to keep the API clean and neat, and the usage easy, this is just one small improvement that could make developing even better. The proposed change save times and debugging for those who forget to do it. But if you don't want it, you can easily exclude it. I could be missing a critical fundamental, but whenever I create libraries, I try not to flood the library with lots of options that could create confusion for someone coming onto it. I have been using PRISM since 2008 in WPF using viewmodel first - it a different animal. View first is something I am learning here. Anything we can do to keep the library clean -- including removing un-needed code, is greatly appreciated in my view. It might break something using an older version, but I don't think that will be a big case, and its obviously very easy to fix.

I personally think the pros outweigh the cons in this case.

I'm not a fan of hidden magic, and with your XAML templates you are been explicit about, hey I have this great feature that if you set to true you would get it, So I think you shouldn't change it, my current use case is that I'm trying to use a Static ViewModelLocator pattern to provide design data time to the new XAML previewer (still in beta channel) and for the XAML ReSharper auto-completion (xcc tool for conditional compilation only works on VS) so right now I'm struggling with: How can I use this great Prism library but at the same time use this 2 features I love, so for now I'm just putting in XAML BindingContext="{x:Static local:DesignViewModelLocator.MyPageViewModel}" and not using the prism:ViewModelLocator.AutowireViewModel="True", so I think we need more and option on the library for supporting this new features that are coming to Xamarin.Forms XAML, than changing what we have been using and works.

I couldn't find an easy way of using Static ViewModelLocator pattern with Prism to be able to satisfy the ReSharper auto-complete tool and Xamarin XAML Previewer,
@brianlagunas Do you know if is possible to ignore BindingContext="{x:Static local:DesignViewModelLocator.MyPageViewModel}" at runtime if prism:ViewModelLocator.AutowireViewModel="True" ?

There is no Designer or concept of "DesignMode" in Xamarin.Forms. I don't know of anyway to detect this currently. I would have to research this.

Oh maybe I couldn't explain well, if you check this @JamesMontemagno article: Xamarin.Forms XAML Previewer Design Time Data in the first comment someone put it

Fantastic for an old SL/WPF dev to see XF get one step closer!
However, since you're actually setting the BindingContext, I don't see how this would jam with Prism and other frameworks

in another comment @Rasmus Christensen said he made that possible for MVVMLight article link

Also I fixed ReSharper for VS adding this to XAML:

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
mc:Ignorable="d"
xmlns:rootViewModel="clr-namespace:IBetU;assembly=IBetU"
d:DataContext="{d:DesignInstance rootViewModel:PawnShopPageViewModel}"

and using this library: XCC for pre-process and remove those xaml lines, but unfortunately that library break the build on Xamarin Studio( I think because of this line )

So my question: Is possible to ignoreBindingContext="" on XAML if we set prism:ViewModelLocator.AutowireViewModel="True" ?

No, Rasmus said he blogged about ViewModelLocator, not swapping out VMs with a Design VM at design time, and a different VM at runtime. You should play around with your idea and let me know what you find.

Ok, but what I want is not swap VMs, I just need to set the VM to a View in XAML without breaking Prism and doing the same things you do in your VMLocatorProvider on auto wire changed callback, so maybe a new kind of factory for vm, I really don't know just asking for your advice.
Thank You.

I don't know own either. I haven't tried this before. Please keep this thread focused on just the original issue.

Personally, having been using this since right after the first preview release of PRISM XF, I think it is a great idea. Especially for people new to the whole concept of Xamarin, which I would guess there will be a lot of given it's newly open source nature. The more PRISM becomes a plug it in and forget it, and the easier it is to use, the broader appeal it will have. Sure for many, or even most of us early adopters, it is great to know exactly what is happening and anything that smells of "magic" is bad. So being able to override things, or even redundantly putting in the AutoWire lines in for those people makes sense. But for those who just want something to work, I think the less steps to make it do so, the better.

Of course it is a great idea to automatically set AutowireViewModel true!
Just add a commented line of code to the template that sets it back to false, and write above it: "//Uncomment this line to disable AutowireViewModel, etc".

As a new Xamarin Forms and Prism user, I had some trouble to understand why on earth do I have to set AutowireViewModel to true since, if I use Prism, I use it to make a MVVM app. It may be usefull to be able to unwire a view and its viewmodel, but this is an alternative use, not the primary one in my opinion.
So go for it!

So I did a little research and it seems that currently, I can't determine the difference between the AutowireViewModel property being set to false and not being defined at all. Unlike in WPF where we have UnsetValue to determine if an attached property has been defined on an object, Xamarin.Forms does not have this value. So I cannot check if it has not been defined, or just set to false. Because of this, I have to continue to require the manual addition of the property.

What I could do is change the data type of the AVM property to a Nullable and set the default to null. Then I would know if it was set to false or not defined (null). But, I'm not sure what impact this would have on current apps if any.

By the way, I am leaning towards adding this feature since it really is core to the guidance Prism for XF provides. I need to decide by next week as I plan on releasing Prism 6.2 as stable :)

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brianlagunas picture brianlagunas  路  47Comments

dansiegel picture dansiegel  路  101Comments

weitzhandler picture weitzhandler  路  30Comments

ericwj picture ericwj  路  39Comments

brianlagunas picture brianlagunas  路  42Comments