MvvmAIO.Prism.SourceGenerators
0.1.5
See the version list below for details.
dotnet add package MvvmAIO.Prism.SourceGenerators --version 0.1.5
NuGet\Install-Package MvvmAIO.Prism.SourceGenerators -Version 0.1.5
<PackageReference Include="MvvmAIO.Prism.SourceGenerators" Version="0.1.5"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="MvvmAIO.Prism.SourceGenerators" Version="0.1.5" />
<PackageReference Include="MvvmAIO.Prism.SourceGenerators"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add MvvmAIO.Prism.SourceGenerators --version 0.1.5
#r "nuget: MvvmAIO.Prism.SourceGenerators, 0.1.5"
#:package MvvmAIO.Prism.SourceGenerators@0.1.5
#addin nuget:?package=MvvmAIO.Prism.SourceGenerators&version=0.1.5
#tool nuget:?package=MvvmAIO.Prism.SourceGenerators&version=0.1.5
Prism.SourceGenerators
Roslyn source generators for the Prism MVVM library.
CI Status
- Open the workflow page above to see the latest pipeline status.
- The
Testsbadge displays the latest passed/failed/skipped counts. - The run also uploads a
test-resultsartifact (.trx) for detailed test reports.
Project Structure
Prism.SourceGenerators/ # Shared project (.shproj/.projitems/.props + source code)
Prism.SourceGenerators.Roslyn4001/ # Roslyn 4.0.1
Prism.SourceGenerators.Roslyn4031/ # Roslyn 4.3.1
Prism.SourceGenerators.Roslyn4120/ # Roslyn 4.12.0
Prism.SourceGenerators.Roslyn5000/ # Roslyn 5.0.0
Prism.SourceGenerators.Samples.Prism9/ # Avalonia 12 sample (Prism 9.0, native AsyncDelegateCommand)
Prism.SourceGenerators.Samples.Prism8/ # Avalonia 12 sample (Prism 8.x, polyfill AsyncDelegateCommand)
Generators
[ObservableProperty]
Generates observable properties for classes inheriting from BindableBase. Supports two usage modes depending on the C# language version.
Field target (all C# versions)
Annotate a private field with [ObservableProperty] to generate a public property that calls SetProperty in the setter.
// C# 12 or earlier
using Prism.SourceGenerators;
public partial class MainViewModel : BindableBase
{
[ObservableProperty]
private string _title = "Hello";
// Generated: public string Title { get => _title; set => SetProperty(ref _title, value); }
}
Partial property target (C# 13+ with field keyword)
Annotate a partial property with [ObservableProperty] to generate the implementing declaration using the field keyword (semi-auto property).
// C# 13+ / .NET 9+ (requires LangVersion 13.0+ or preview)
using Prism.SourceGenerators;
public partial class MainViewModel : BindableBase
{
[ObservableProperty]
public partial string Title { get; set; } = "Hello";
// Generated: public partial string Title { get => field; set => SetProperty(ref field, value); }
}
The partial property approach eliminates the need for a separate backing field and provides a cleaner API surface. Both modes can coexist in the same project.
OnChanged partial methods
For every [ObservableProperty], the generator emits two partial method declarations that you can optionally implement to react to changes:
public partial class MainViewModel : BindableBase
{
[ObservableProperty]
public partial int Age { get; set; }
// Generated declarations (implement one or both):
// partial void OnAgeChanged(int value);
// partial void OnAgeChanged(int oldValue, int newValue);
partial void OnAgeChanged(int oldValue, int newValue)
{
Debug.WriteLine($"Age changed from {oldValue} to {newValue}");
}
}
The generated setter uses EqualityComparer<T>.Default.Equals for change detection and calls both OnChanged overloads before raising PropertyChanged.
[NotifyPropertyChangedFor]
Apply to a field or partial property alongside [ObservableProperty] to automatically raise PropertyChanged for additional dependent properties when the annotated property changes.
public partial class MainViewModel : BindableBase
{
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(FullName))]
private string _firstName = "";
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(FullName))]
private string _lastName = "";
public string FullName => $"{FirstName} {LastName}";
}
Supports multiple property names via [NotifyPropertyChangedFor(nameof(A), nameof(B))] or multiple attribute instances.
[DelegateCommand]
Generates DelegateCommand or AsyncDelegateCommand properties from methods.
- Synchronous methods (
void) generateDelegateCommand/DelegateCommand<T> - Async methods (
Task) generateAsyncDelegateCommand/AsyncDelegateCommand<T> - For Prism < 9.0 (which lacks
AsyncDelegateCommand), a polyfill is generated automatically - C# 14+: Command properties use the
fieldkeyword (no separate backing field) - C# 13 and earlier: Command properties use a traditional backing field
using Prism.SourceGenerators;
public partial class MainViewModel : BindableBase
{
// Generates: DelegateCommand IncrementCommand
[DelegateCommand]
private void Increment() { /* ... */ }
// Generates: AsyncDelegateCommand LoadDataCommand
[DelegateCommand]
private async Task LoadDataAsync() { /* ... */ }
// With CanExecute support
[DelegateCommand(CanExecute = nameof(CanSubmit))]
private void Submit() { /* ... */ }
private bool CanSubmit() => true;
}
Generated output comparison
C# 14+ (LangVersion >= 14) — uses field keyword:
// No backing field needed
public DelegateCommand IncrementCommand => field ??= new DelegateCommand(Increment);
C# 13 and earlier — traditional backing field:
private DelegateCommand? _incrementCommand;
public DelegateCommand IncrementCommand => _incrementCommand ??= new DelegateCommand(Increment);
[AsyncDelegateCommand]
Dedicated attribute for async methods with advanced Prism 9.0+ features.
Supports fluent configuration: EnableParallelExecution, CancelAfter, Catch, CancellationTokenSourceFactory.
using Prism.SourceGenerators;
public partial class MainViewModel : BindableBase
{
// Parallel execution enabled
[AsyncDelegateCommand(EnableParallelExecution = true)]
private async Task FetchDataAsync() { /* ... */ }
// With error handling and CanExecute
[AsyncDelegateCommand(CanExecute = nameof(CanSave), Catch = nameof(HandleError))]
private async Task SaveAsync() { /* ... */ }
private bool CanSave() => true;
private void HandleError(Exception ex) { /* ... */ }
}
[ObservesProperty]
Automatically re-evaluates CanExecute when the specified properties change.
Works with both [DelegateCommand] and [AsyncDelegateCommand].
using Prism.SourceGenerators;
public partial class MainViewModel : BindableBase
{
[ObservableProperty]
private bool _isValid;
[DelegateCommand(CanExecute = nameof(CanSubmit))]
[ObservesProperty(nameof(IsValid))]
private void Submit() { /* ... */ }
// Multiple properties
[AsyncDelegateCommand(CanExecute = nameof(CanSave))]
[ObservesProperty(nameof(Counter), nameof(IsActive))]
private async Task SaveAsync() { /* ... */ }
}
[BindableBase]
Apply to a class that does not inherit from Prism.Mvvm.BindableBase to automatically generate an INotifyPropertyChanged implementation. The generated code includes PropertyChanged event, SetProperty<T>, RaisePropertyChanged, and OnPropertyChanged methods.
using Prism.SourceGenerators;
[BindableBase]
public partial class SimpleViewModel
{
private string _message = "Hello!";
public string Message
{
get => _message;
set => SetProperty(ref _message, value);
}
}
If the class already inherits from BindableBase or a base class that implements INotifyPropertyChanged, no code is generated.
Diagnostics
| ID | Description |
|---|---|
| PSG0001 | Class with [ObservableProperty] members must be partial |
| PSG0002 | Class with [DelegateCommand] / [AsyncDelegateCommand] method must be partial |
| PSG0003 | Property with [ObservableProperty] must be declared as partial |
| PSG0004 | Class with [BindableBase] must be partial |
| PSG1001 | Method signature is invalid for [DelegateCommand] |
| PSG1002 | Method signature is invalid for [AsyncDelegateCommand] |
| PSG2001 | Catch handler member was not found |
| PSG2002 | Catch handler signature is not compatible |
| PSG2003 | CanExecute member was not found |
| PSG2004 | Observed property was not found |
| PSG3001 | AsyncDelegateCommand polyfill is active (Prism < 9.0) |
Installation
<PackageReference Include="MvvmAIO.Prism.SourceGenerators" Version="0.1.2" />
Or:
dotnet add package MvvmAIO.Prism.SourceGenerators
Building
dotnet build Prism.SourceGenerators.slnx
Nuke Build
This repository uses Nuke as the build orchestration layer for local automation and CI.
- Main source solution:
Prism.SourceGenerators.slnx - Build automation solution:
build.slnx(contains onlybuild/_build.csproj)
Common commands:
# CI pipeline locally (clean + restore + compile + test)
dotnet run --project build/_build.csproj -- --target Ci --configuration Release
# Pack NuGet package (optionally override version)
dotnet run --project build/_build.csproj -- --target Pack --configuration Release --version 0.1.2
# Publish NuGet package
dotnet run --project build/_build.csproj -- --target Publish --configuration Release --version 0.1.2 --nuget-api-key <NUGET_API_KEY>
Requirements
- .NET 10 SDK
- Visual Studio 2022 17.13+ / Rider / VS Code with C# Dev Kit (for
.slnxsupport)
Learn more about Target Frameworks and .NET Standard.
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.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.8.1 | 48 | 6/30/2026 |
| 0.8.0 | 48 | 6/30/2026 |
| 0.7.0 | 94 | 6/29/2026 |
| 0.5.1 | 118 | 5/31/2026 |
| 0.5.0 | 112 | 5/26/2026 |
| 0.4.3 | 100 | 5/26/2026 |
| 0.4.2 | 105 | 5/25/2026 |
| 0.4.1 | 108 | 5/16/2026 |
| 0.4.0 | 102 | 5/13/2026 |
| 0.3.1 | 92 | 5/5/2026 |
| 0.3.0 | 104 | 5/5/2026 |
| 0.2.2 | 99 | 5/1/2026 |
| 0.2.1 | 101 | 5/1/2026 |
| 0.2.0 | 95 | 5/1/2026 |
| 0.1.7 | 95 | 5/1/2026 |