MvvmAIO.Prism.SourceGenerators
0.1.0
See the version list below for details.
dotnet add package MvvmAIO.Prism.SourceGenerators --version 0.1.0
NuGet\Install-Package MvvmAIO.Prism.SourceGenerators -Version 0.1.0
<PackageReference Include="MvvmAIO.Prism.SourceGenerators" Version="0.1.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="MvvmAIO.Prism.SourceGenerators" Version="0.1.0" />
<PackageReference Include="MvvmAIO.Prism.SourceGenerators"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add MvvmAIO.Prism.SourceGenerators --version 0.1.0
#r "nuget: MvvmAIO.Prism.SourceGenerators, 0.1.0"
#:package MvvmAIO.Prism.SourceGenerators@0.1.0
#addin nuget:?package=MvvmAIO.Prism.SourceGenerators&version=0.1.0
#tool nuget:?package=MvvmAIO.Prism.SourceGenerators&version=0.1.0
Prism.SourceGenerators
Roslyn source generators for the Prism MVVM library.
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/ # WPF sample (Prism 9.0, native AsyncDelegateCommand)
Prism.SourceGenerators.Samples.Prism8/ # WPF 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 |
Building
dotnet build Prism.SourceGenerators.slnx
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 | 47 | 6/30/2026 |
| 0.8.0 | 48 | 6/30/2026 |
| 0.7.0 | 92 | 6/29/2026 |
| 0.5.1 | 118 | 5/31/2026 |
| 0.5.0 | 109 | 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 | 99 | 5/13/2026 |
| 0.3.1 | 92 | 5/5/2026 |
| 0.3.0 | 101 | 5/5/2026 |
| 0.2.2 | 99 | 5/1/2026 |
| 0.2.1 | 98 | 5/1/2026 |
| 0.2.0 | 95 | 5/1/2026 |
| 0.1.7 | 95 | 5/1/2026 |