NotifyGen 1.0.0
See the version list below for details.
dotnet add package NotifyGen --version 1.0.0
NuGet\Install-Package NotifyGen -Version 1.0.0
<PackageReference Include="NotifyGen" Version="1.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="NotifyGen" Version="1.0.0" />
<PackageReference Include="NotifyGen"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add NotifyGen --version 1.0.0
#r "nuget: NotifyGen, 1.0.0"
#:package NotifyGen@1.0.0
#addin nuget:?package=NotifyGen&version=1.0.0
#tool nuget:?package=NotifyGen&version=1.0.0
NotifyGen
A C# source generator that eliminates INotifyPropertyChanged boilerplate.
NotifyGen automatically generates property implementations with change notification from annotated fields. No runtime reflection, no IL weaving, just clean generated code.
Features
- Zero boilerplate - Just add
[Notify]to your class - Compile-time generation - No runtime overhead
- Equality guards - Only raises
PropertyChangedwhen values actually change - Partial hooks -
OnXxxChanged()methods for custom logic - Dependent properties -
[NotifyAlso]for computed properties - IDE support - Full IntelliSense for generated properties
- Nullable aware - Handles nullable reference types correctly
Installation
dotnet add package NotifyGen
Or via NuGet Package Manager:
Install-Package NotifyGen
Quick Start
using NotifyGen;
[Notify]
public partial class Person
{
private string _name;
private int _age;
private string? _email;
}
That's it! NotifyGen generates the following:
public partial class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public string Name
{
get => _name;
set
{
if (EqualityComparer<string>.Default.Equals(_name, value)) return;
_name = value;
OnPropertyChanged();
OnNameChanged();
}
}
public int Age
{
get => _age;
set
{
if (EqualityComparer<int>.Default.Equals(_age, value)) return;
_age = value;
OnPropertyChanged();
OnAgeChanged();
}
}
public string? Email
{
get => _email;
set
{
if (EqualityComparer<string?>.Default.Equals(_email, value)) return;
_email = value;
OnPropertyChanged();
OnEmailChanged();
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
partial void OnNameChanged();
partial void OnAgeChanged();
partial void OnEmailChanged();
}
Attributes
[Notify]
Apply to a partial class to enable property generation for all private fields with underscore prefix.
[Notify]
public partial class ViewModel
{
private string _title; // Generates Title property
private int _count; // Generates Count property
}
Requirements:
- Class must be
partial - Fields must be
private - Fields must start with underscore (
_fieldName→FieldName)
[NotifyIgnore]
Exclude a field from property generation.
[Notify]
public partial class ViewModel
{
private string _name; // Generates Name property
[NotifyIgnore]
private string _internalCache; // No property generated
}
[NotifyAlso]
Notify additional properties when this field changes. Useful for computed/dependent properties.
[Notify]
public partial class Person
{
[NotifyAlso("FullName")]
private string _firstName;
[NotifyAlso("FullName")]
private string _lastName;
public string FullName => $"{FirstName} {LastName}";
}
When FirstName or LastName changes, PropertyChanged is also raised for FullName.
You can notify multiple properties:
[NotifyAlso("FullName")]
[NotifyAlso("DisplayName")]
private string _firstName;
Partial Hooks
Every generated property includes a partial method hook that's called after the value changes:
[Notify]
public partial class Settings
{
private bool _darkMode;
partial void OnDarkModeChanged()
{
// Called whenever DarkMode changes
ApplyTheme(DarkMode ? Theme.Dark : Theme.Light);
}
}
Analyzer Diagnostics
NotifyGen includes analyzers to catch common mistakes:
| Code | Severity | Description |
|---|---|---|
| NOTIFY001 | Error | Class marked with [Notify] must be partial |
| NOTIFY002 | Warning | No eligible fields found (no underscore-prefixed private fields) |
Requirements
- .NET Standard 2.0+ (works with .NET Framework 4.6.1+, .NET Core, .NET 5+)
- C# 9.0+ (for source generators)
Comparison to Alternatives
| Feature | NotifyGen | Fody.PropertyChanged | CommunityToolkit.Mvvm |
|---|---|---|---|
| Generation | Source Generator | IL Weaving | Source Generator |
| Runtime dependency | None | None | Runtime library |
| Build speed | Fast | Slower | Fast |
| Debugging | Full support | Limited | Full support |
| Configuration | Attributes | Attributes + Config | Attributes |
| Equality check | Built-in | Built-in | Optional |
| Partial hooks | Yes | Limited | Yes |
Troubleshooting
Properties not generating?
- Ensure your class is
partial - Ensure fields are
private - Ensure fields start with underscore (
_name, notname) - Rebuild the solution
IntelliSense not showing generated properties?
- Rebuild the solution
- Restart your IDE
- Check that the NotifyGen package is properly referenced
Build errors after adding [Notify]?
Check the Error List for NOTIFY001/NOTIFY002 diagnostics - they provide guidance on what's wrong.
Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
License
This project is licensed under the MIT License - see the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.