Source Generators and Fody, the easy way to create properties in ReactiveUI¶
Legacy Note¶
If you are tired of writing boilerplate code for property change notifications, you can try one of the following:
These two libraries are both based on Fody - an extensible tool for weaving .NET assemblies, and they'll
inject INotifyPropertyChanged code into decorated properties at compile time for you.
Recommend for new projects¶
- ReactiveUI.SourceGenerators documents every attribute, and Migrating from Fody shows how to move existing code.
This library is a Source Generator that generates properties and commands for you. It is a new way to generate properties and commands for ReactiveUI taking decorated fields and methods and generating the properties and ReactiveCommands for you.
We recommend using ReactiveUI.SourceGenerators package that also handles ReactiveCommands.
For ObservableAsPropertyHelper<T> properties, use the [ObservableAsProperty] attribute from ReactiveUI.Binding.
The manual way to create properties in ReactiveUI¶
Read-write properties¶
Typically properties are declared like this:
private string _name;
public string Name
{
get => _name;
set => this.RaiseAndSetIfChanged(ref _name, value);
}
ObservableAsPropertyHelper properties¶
Similarly, to declare output properties, the code looks like this:
ObservableAsPropertyHelper<string> _firstName;
public string FirstName => _firstName.Value;
Then the helper is initialized with a call to ToProperty:
// firstNameObservable is IObservable<string>
_firstName = firstNameObservable
.ToProperty(this, x => x.FirstName);
Using ReactiveUI.Fody - Legacy¶
Strongly discouraged for new projects¶
With ReactiveUI.Fody, you don't have to write boilerplate code for getters and setters of read-write properties — the package will do it automagically for you at compile time.
All you have to do is annotate the property with the [Reactive] attribute, as shown below.
ReactiveUI.Fody - Read-write properties¶
[Reactive]
public string Name { get; set; }
Note
ReactiveUI.Fodycurrently doesn't support inline auto property initializers in generic types. It works fine with non-generic types. But if you are working on a generic type, don't attempt to write code likepublic string Name { get; set; } = "Name";, this won't work as you might expect and will likely throw a very weird exception. To workaround this limitation, move your property initialization code to the constructor of your view model class. We know about this limitation and have a tracking issue for this.
ReactiveUI.Fody - ObservableAsPropertyHelper properties¶
With ReactiveUI.Fody, you can simply declare a read-only property using the [ObservableAsProperty] attribute, using either option of the two options shown below. One option is to annotate the getter of the property:
public string FirstName { [ObservableAsProperty] get; }
Another option is to annotate the property as a whole:
[ObservableAsProperty]
public string FirstName { get; }
The field will be generated and the property implemented at compile time. Because there is no field for you to pass to .ToProperty, you should use the .ToPropertyEx extension method provided by this library:
// firstNameObservable is IObservable<string>
firstNameObservable.ToPropertyEx(this, x => x.FirstName);
This extension will assign the auto-generated field for you rather than relying on the out parameter.
Note The generated getter for property of type
Tannotated with the[ObservableAsProperty]attribute will returndefault(T)in case if the property isn't yet initialized via a call toToPropertyEx. To be more specific, the generated getter code looks somewhat likeT PropertyName => oaph?.Value ?? default(T);, whereoaphis a field of typeObservableAsProperty<T>which is generated by the compiler.