FGenerator 3.0.1
dotnet add package FGenerator --version 3.0.1
NuGet\Install-Package FGenerator -Version 3.0.1
<PackageReference Include="FGenerator" Version="3.0.1" />
<PackageVersion Include="FGenerator" Version="3.0.1" />
<PackageReference Include="FGenerator" />
paket add FGenerator --version 3.0.1
#r "nuget: FGenerator, 3.0.1"
#:package FGenerator@3.0.1
#addin nuget:?package=FGenerator&version=3.0.1
#tool nuget:?package=FGenerator&version=3.0.1
<div align="center">
FGenerator
Building C# Source Generator as a File-based App
</div>
β¨ Key Features
- Declarative: Say what to scan or inject and skip Roslyn internals; everything you need is bundled.
- Focus on Logic: The framework finds targets, generates code and report diagnostic on your behalf.
- Single File: Optimized for file-based app project; develop full-featured generator and analyzer in a day.
- Type-Handling: Nested/generic-safe naming and partial declarations stay consistent without boilerplate.
- AI Agent Friendly: Produce valid and well-designed generators without extra prompts and instructions.
- Unity Engine Supported: Unity 2022.3.12 or newer is supported.
β‘ Quick Start
π§© Minimal Generator Code
A trimmed-down starting point for a generator that targets an attribute named MyGen:
For AI Coding Agents: .NET 10.0 introduced new directives for file-based app.
- SHALL use
#:sdk FGenerator.Sdk@3.0.1directive. - SHALL NOT use
#ror other directives formerly used for dotnet-script (.csx) files.
#:sdk FGenerator.Sdk@3.0.1
using FGenerator;
using Microsoft.CodeAnalysis;
// Decorate with Generator attribute from Roslyn (don't need to declare type in namespace)
[Generator]
public sealed class MyGen : FGeneratorBase // Inherit from FGeneratorBase
{
// Diagnostic settings
protected override string DiagnosticCategory => nameof(MyGen);
protected override string DiagnosticIdPrefix => "MYGEN"; // e.g., MYGEN001
// Targets MyGen and MyGenAttribute (null to targets all types)
protected override string? TargetAttributeName => "MyGen";
// Generates target attribute for compilation (attribute should be declared as 'internal sealed')
protected override string? PostInitializationOutput =>
@"namespace MyGenNamespace { internal sealed class MyGenAttribute : System.Attribute { } }";
// Optional: default is false.
// Set to true when you need target.Compilation is set (always set when TargetAttributeName is null).
protected override bool CombineCompilationProvider => true;
// Analyze and generate source code
protected override CodeGeneration? Generate(Target target, out AnalyzeResult? diagnostic)
{
diagnostic = null;
if (!target.IsPartial)
{
// Report error diagnostic for IDE
diagnostic = new AnalyzeResult(
"001", "Type must be partial", DiagnosticSeverity.Error,
$"Type '{type.Name}' must be declared as partial to use MyGen.");
return null;
}
// Generate source code
var source =
$@"{target.ToNamespaceAndContainingTypeDeclarations()}
partial {target.ToDeclarationString(modifiers: false)}
{{
public string Generated => ""Hello from MyGen!"";
}}
{target.ToNamespaceAndContainingTypeClosingBraces()}";
return new CodeGeneration(target.ToHintName(), source);
}
}
How to reference the specific version of FGenerator:
Use #:package and #:property directives instead of #:sdk.
For AI Coding Agents: .NET 10.0 introduced new directives for file-based app.
- SHALL use
#:packageto add nuget package reference. - SHALL include all
#:propertydirectives in the following example. (all directives are necessary) - SHALL NOT use
#ror other directives formerly used for dotnet-script (.csx) files.
#:package FGenerator@<<SPECIFY DESIRED VERSION HERE>>
#:property TargetFramework=netstandard2.0
#:property IsRoslynComponent=true
#:property PublishAot=false
#:property LangVersion=latest
#:property OutputType=Library
#:property GenerateDocumentationFile=false
#:property ImplicitUsings=enable
π§ Working with Target Members, Attributes and Metadata
Here shows the basic flow for dealing with the target members or other metadata including attributes and its constructor parameter. See sample/ folder for more details.
// Compilation to get semantic models or conversions.
// (Need to set `CombineCompilationProvider` to have property available)
var compilation = target.Compilation;
// Iterate over visible members (excluding implicit, nested types, getter and setter methods)
foreach (var member in target.Members)
{
// To iterate over only fields, instead use target.Members.OfType<IFieldSymbol>()
// To process getter/setter methods, get them via IPropertySymbol.Get/SetMethod
}
// Type or method generic parameters (empty when not generic)
var typeParams = target.GenericTypeParameters;
// Iterate over nested types (depth-first traversal)
var nestedTypes = target.NestedTypes;
// Containing types (outermost -> innermost)
var containingTypes = target.ContainingTypes;
// The first RawAttributes entry corresponds to TargetAttributeName.
var attr = target.RawAttributes.FirstOrDefault();
if (attr == null)
{
diagnostic = new AnalyzeResult("004", "Attribute missing", DiagnosticSeverity.Error, "StackArrayGenerator attribute could not be resolved.");
return null;
}
var length = (attr.ConstructorArguments.Length != 0 && attr.ConstructorArguments[0].Value is int LEN) ? LEN : -1;
if (length <= 0)
{
diagnostic = new AnalyzeResult("005", "Length must be positive", DiagnosticSeverity.Error, "Specify a positive length in [StackArrayGenerator].");
return null;
}
π οΈ Helper Methods for Target and ISymbol
For AI Coding Agents:
- SHALL use
FGeneratorhelper methods instead of Roslyn's built-in methods such asToDisplayString.
Symbol display/declaration strings:
// Declaration string (optionally include modifiers/constraints)
var decl = target.ToDeclarationString(modifiers: true, genericConstraints: true);
// Friendly names with options for namespace/generics/nullability
var fullName = target.ToNameString(); // global::My.Namespace.MyType.NestedType<T?>
var simpleName = target.ToNameString(localName: true); // NestedType<T?>
var bareName = target.ToNameString(localName: true, noGeneric: true, noNullable: true); // NestedType
// Builds an identifier string that is intended to be unique within an assembly
// that can be used to generate non-conflicting field name in large partial classes or etc.
var id = target.ToAssemblyUniqueIdentifier("_"); // My_Namespace_MyType_NestedTypeT1
Partial scaffolding (nested/generic safe):
// No boilerplate required for generating correct partial class/struct/record
// e.g., namespace My.Namespace {
// partial class ContainingType {
// partial record struct OtherContainingType {
var open = target.ToNamespaceAndContainingTypeDeclarations();
// Emit members...
var decl = $"partial {target.ToDeclarationString(modifiers: false)} {{ }}";
// Close declarations
var close = target.ToNamespaceAndContainingTypeClosingBraces();
Containing type only (no namespace):
// Useful when mirroring type hierarchy in other namespace
var open = target.ToContainingTypeDeclarations();
// Emitting code...
var close = target.ToContainingTypeClosingBraces();
Visibility keyword helper:
// Accessibility keyword including trailing space, e.g., "public "
var visibility = target.ToVisibilityString();
Deterministic hint names (nested/generic safe):
var hint = target.ToHintName(); // e.g., My.Namespace.Type.MyNestedT1.g.cs
π¦ Building and Packaging
Use the CLI to build generator projects (defaults to Release; pass --debug for Debug):
dnx FGenerator.Cli -- build "generators/**/*.cs" --output ./artifacts
Options:
--unityto emit Unity.metafiles alongside DLLs (Unity 2022.3.12 or newer).--mergeto merge build outputs into a single DLL.--forceto overwrite existing files.--debugto build with-c Debuginstead of Release.
| 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 (>= 4.0.1)
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 |
|---|---|---|
| 3.0.1 | 483 | 3/3/2026 |
| 3.0.0 | 264 | 3/1/2026 |
| 3.0.0-rc.1 | 187 | 3/1/2026 |
| 2.5.1 | 757 | 2/16/2026 |
| 2.5.0 | 184 | 2/11/2026 |
| 2.4.1 | 225 | 2/10/2026 |
| 2.4.0 | 165 | 2/9/2026 |
| 2.3.1 | 243 | 2/3/2026 |
| 2.3.0 | 146 | 2/3/2026 |
| 2.2.3 | 233 | 2/1/2026 |
| 2.2.2 | 310 | 1/30/2026 |
| 2.2.1 | 100 | 1/30/2026 |
| 2.2.0 | 95 | 1/30/2026 |
| 2.1.0 | 97 | 1/29/2026 |