Cleaning up MVVMCross ViewModels with Fody

Denys Fiediaiev
3 min readMar 31, 2021

Have you noticed that the more complex the UI is, the more repetitive code appears in the ViewModel? And especially, the code related to “live” properties is duplicated.

Despite the fact that refactoring is always challenging, you can start a ViewModel’s code clean-up by involving the PropertyChanged weaving library based on the tool called Fody.

Even if you are familiar with this library, the advanced usage section could still be helpful.

Our demo ViewModel contains FirstName, LastName and Email properties that are “live” properties, e.g., the PropertyChanged event should be invoked when any of these properties are changed.

As you can see, there is a lot of repeatable code, and several ways to raise the property changed even. If you run the app, the output will be like this:

Live property updates are printed to the console using the default MvvmCross property notifications.

Let’s see how this code can be cleaned up using the PropertyChanged library.

Setup

All we need is to add the PropertyChanged.Fody package to the project that contains the ViewModel layer:

PropertyChanged.Fody package can be found and added using the default NuGet manager in Rider IDE.

The FodyWeavers.xml file will be added automatically:

PropertyChanged weaver should be set in the Fody config to work correctly.

Basic Usage

As the MvxViewModel already implements INotifyPropertyChanged, no changes are required except for removing manual RaisePropertyChanged method calls.

Much cleaner, isn’t it?

Advanced Usage

Here are the most useful advanced features, but the full features list is available in the official documentation.

Ignoring Unneeded Properties

There is no end to optimization, and ignoring unnecessary PropertyChanged events can speed up your application a bit. To do that, you need to add the [DoNotNotify] attribute to the property you want to ignore:

[DoNotNotify]
public string Email { get; set; }

Now our debug output does not contain the Email line because the property is not “live” anymore:

No PropertyChanged events raised for ignored Email property.

Property Interception

If you need some additional logic (like validation) when the property is set, you can add an interception method using the particular signature On<Property>Changed:

public string Email { get; set; }

// ReSharper disable once UnusedMember.Local
private void OnEmailChanged()
{
Debug.WriteLine($"New email is: {Email}");
}

Ignoring Unneeded Methods

Sometimes our method names are similar to those used by the Fody.PropertyChanged library:

Connectivity event subscription conflicts with Fody.PropertyChanged methods signature.

And warnings appear during the build process:

Method conflicts end up with build-time warnings.

To resolve them, you need to add an attribute [SuppressPropertyChangedWarnings] specified in the unsupported method’s warning message:

[SuppressPropertyChangedWarnings]
private void OnConnectivityChanged(
object sender,
ConnectivityChangedEventArgs e
)
{
Debug.WriteLine($"Is Connected: {e.IsConnected}");
}

Code readability is one of the essential things in software development: a clean and straightforward code speedups its maintenance and reduces the chance to introduce a bug. Applying that tiny PropertyChanged library worth nothing but significantly improves readability.

Don’t forget to check out other Fody-based libraries here:

Happy cleaning! 😉

--

--

Denys Fiediaiev

Xamarin | iOS | Android Developer with 8 years of experience. All things actionable tips, real-life examples and coding guides to help you grow professionally.