PrimaryConstructor.Readonly
1.0.0
dotnet add package PrimaryConstructor.Readonly --version 1.0.0
NuGet\Install-Package PrimaryConstructor.Readonly -Version 1.0.0
<PackageReference Include="PrimaryConstructor.Readonly" Version="1.0.0" />
<PackageVersion Include="PrimaryConstructor.Readonly" Version="1.0.0" />
<PackageReference Include="PrimaryConstructor.Readonly" />
paket add PrimaryConstructor.Readonly --version 1.0.0
#r "nuget: PrimaryConstructor.Readonly, 1.0.0"
#:package PrimaryConstructor.Readonly@1.0.0
#addin nuget:?package=PrimaryConstructor.Readonly&version=1.0.0
#tool nuget:?package=PrimaryConstructor.Readonly&version=1.0.0
AutoReadonlyFields Source Generator
A C# Incremental Source Generator that automatically creates private readonly fields from C# 12 Primary Constructor parameters.
🚀 The Problem
C# 12 introduced Primary Constructors, which are great for dependency injection. However, if you want to store those parameters as private fields to use them across your class methods, you still have to manually declare the fields and assign them:
// ❌ The old/manual way
public class UserService(ILogger logger, IRepository repo)
{
// You have to manually type this boilerplate
private readonly ILogger _logger = logger;
private readonly IRepository _repo = repo;
public void DoWork() => _logger.Log("Working...");
}
✨ The Solution
With this generator, simply mark your parameters with [Readonly] and the fields are generated for you automatically.
// ✅ The new way
public partial class UserService(
[Readonly] ILogger logger,
[Readonly] IRepository repo)
{
// Fields _logger and _repo are auto-generated!
public void DoWork() => _logger.Log("Working...");
}
📦 Requirements
- .NET SDK: 6.0 or higher
- Language Version: C# 12 or higher (required for Primary Constructors)
🛠 Installation
Option 1: Project Reference (Local Development)
If you are including the generator source code directly in your solution:
- Add the
PrimaryConstructor.Readonlyproject to your solution. - In your consuming project's
.csproj(e.g.,MyApp.csproj), add the reference with specific attributes:
<ItemGroup>
<ProjectReference Include="..\PrimaryConstructor.Readonly\PrimaryConstructor.Readonly"
OutputItemType="Analyzer"/>
</ItemGroup>
Option 2: NuGet (If you package it)
(Skip this if you are just running it locally)
<PackageReference Include="PrimaryConstructor.Readonly" Version="1.0.0" PrivateAssets="all" />
💻 Usage
1. Create a Partial Class
Create a class using a Primary Constructor. You must add the partial keyword.
public partial class MyService([Readonly] HttpClient client)
{
public async Task GetData()
{
// usage of _client is valid here because the generator created it
var response = await _client.GetAsync("https://example.com");
}
}
3. Build Project
The generator runs during the build process. Once built, you will see the generated files under your Dependencies/Analyzers node in Visual Studio.
⚙️ How it Works
The generator:
- Scans for classes marked
partialwith a Primary Constructor. - Looks for parameters decorated with
[Readonly]. - Generates a separate partial class file containing:
private readonly Type _paramName = paramName; - It handles Generic types (
MyClass<T>) and Namespaces automatically.
| 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. |
-
.NETStandard 2.0
- Microsoft.CodeAnalysis.CSharp (>= 5.0.0)
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 |
|---|---|---|
| 1.0.0 | 317 | 12/16/2025 |