FractalDataWorks.SmartGenerators.CodeBuilders
0.1.5-alpha-g8cae162c25
dotnet add package FractalDataWorks.SmartGenerators.CodeBuilders --version 0.1.5-alpha-g8cae162c25
NuGet\Install-Package FractalDataWorks.SmartGenerators.CodeBuilders -Version 0.1.5-alpha-g8cae162c25
<PackageReference Include="FractalDataWorks.SmartGenerators.CodeBuilders" Version="0.1.5-alpha-g8cae162c25"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="FractalDataWorks.SmartGenerators.CodeBuilders" Version="0.1.5-alpha-g8cae162c25" />
<PackageReference Include="FractalDataWorks.SmartGenerators.CodeBuilders"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add FractalDataWorks.SmartGenerators.CodeBuilders --version 0.1.5-alpha-g8cae162c25
#r "nuget: FractalDataWorks.SmartGenerators.CodeBuilders, 0.1.5-alpha-g8cae162c25"
#:package FractalDataWorks.SmartGenerators.CodeBuilders@0.1.5-alpha-g8cae162c25
#addin nuget:?package=FractalDataWorks.SmartGenerators.CodeBuilders&version=0.1.5-alpha-g8cae162c25&prerelease
#tool nuget:?package=FractalDataWorks.SmartGenerators.CodeBuilders&version=0.1.5-alpha-g8cae162c25&prerelease
FractalDataWorks Smart Generators
A comprehensive toolkit for building, testing, and deploying Roslyn source generators with a fluent code generation API.
Table of Contents
Overview
FractalDataWorks Smart Generators provides a complete framework for building Roslyn source generators:
- Fluent Code Building API - Generate C# code with an intuitive builder pattern
- Incremental Generator Base Classes - Simplified development with best practices built-in
- Comprehensive Testing Framework - Test generators with expectations and assertions
- Documentation Support - Extract and format XML documentation
Projects
This solution contains three main projects:
FractalDataWorks.SmartGenerators
Core framework for building incremental source generators with utilities for diagnostics, compilation helpers, and base classes.
FractalDataWorks.SmartGenerators.CodeBuilders
Fluent API for generating C# code including classes, interfaces, methods, properties, and more with proper formatting and documentation.
FractalDataWorks.SmartGenerators.TestUtilities
Testing framework for source generators with compilation builders, assertion helpers, and expectations API.
Installation
Install the packages you need:
# For building generators
dotnet add package FractalDataWorks.SmartGenerators
dotnet add package FractalDataWorks.SmartGenerators.CodeBuilders
# For testing generators
dotnet add package FractalDataWorks.SmartGenerators.TestUtilities
Quick Start
1. Create a Source Generator
using FractalDataWorks.SmartGenerators;
using FractalDataWorks.SmartGenerators.CodeBuilders;
using Microsoft.CodeAnalysis;
[Generator]
public class DtoGenerator : IncrementalGeneratorBase<ClassModel>
{
protected override bool IsRelevantSyntax(SyntaxNode node)
{
return node is ClassDeclarationSyntax cds &&
cds.AttributeLists.Any(al =>
al.Attributes.Any(a => a.Name.ToString().Contains("GenerateDto")));
}
protected override ClassModel? TransformSyntax(GeneratorSyntaxContext context)
{
var classDecl = (ClassDeclarationSyntax)context.Node;
var symbol = context.SemanticModel.GetDeclaredSymbol(classDecl);
return new ClassModel
{
Name = symbol!.Name,
Namespace = symbol.ContainingNamespace.ToDisplayString(),
Properties = symbol.GetMembers()
.OfType<IPropertySymbol>()
.Select(p => new PropertyModel
{
Name = p.Name,
Type = p.Type.ToDisplayString()
})
.ToList()
};
}
protected override void Execute(SourceProductionContext context, ClassModel model)
{
var dto = new ClassBuilder($"{model.Name}Dto")
.MakePublic()
.MakePartial()
.WithNamespace(model.Namespace);
foreach (var prop in model.Properties)
{
dto.AddProperty(prop.Type, prop.Name, p => p
.MakePublic()
.WithGetterAndSetter());
}
context.AddSource($"{model.Name}Dto.g.cs", dto.Build());
}
}
2. Test Your Generator
using FractalDataWorks.SmartGenerators.TestUtilities;
using Xunit;
using Shouldly;
public class DtoGeneratorTests
{
[Fact]
public void GeneratesDto()
{
var source = @"
[GenerateDto]
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}";
var result = SourceGeneratorTestHelper.RunGenerator<DtoGenerator>(source);
result.ShouldContain("public partial class PersonDto");
result.ShouldContain("public int Id { get; set; }");
result.ShouldContain("public string Name { get; set; }");
}
}
Generic Type Support
CodeBuilders now support generic types:
ClassBuilder
var builder = new ClassBuilder("MyClass")
.WithTypeParameter("T")
.WithTypeConstraint("where T : IDisposable")
.MakePublic();
// Generates: public class MyClass<T> where T : IDisposable
Multiple Type Parameters
var builder = new ClassBuilder("Converter")
.WithTypeParameters("TInput", "TOutput")
.WithTypeConstraint("where TInput : class")
.WithTypeConstraint("where TOutput : struct")
.MakePublic();
InterfaceBuilder
Same methods available for interfaces:
var builder = new InterfaceBuilder("IRepository")
.WithTypeParameter("T")
.WithTypeConstraint("where T : IEntity")
.MakePublic();
Architecture
Solution Structure
smart-generators/
├── src/
│ ├── FractalDataWorks.SmartGenerators/ # Core framework
│ ├── FractalDataWorks.SmartGenerators.CodeBuilders/ # Code building API
│ └── FractalDataWorks.SmartGenerators.TestUtilities/ # Testing utilities
├── tests/
│ ├── FractalDataWorks.SmartGenerators.Tests/
│ ├── FractalDataWorks.SmartGenerators.CodeBuilder.Tests/
│ └── FractalDataWorks.SmartGenerators.TestUtilities.Tests/
├── docs/ # Documentation
└── README.md # This file
Component Architecture
graph TD
A[Your Generator] -->|inherits| B[IncrementalGeneratorBase]
A -->|uses| C[Code Builders]
B -->|part of| D[SmartGenerators Core]
C -->|part of| E[CodeBuilders Package]
F[Your Tests] -->|uses| G[Test Utilities]
G -->|references| D
G -->|references| E
Generation Flow
sequenceDiagram
participant Source as Source Code
participant Gen as Your Generator
participant Base as IncrementalGeneratorBase
participant Builder as Code Builder
participant Output as Generated Code
Source->>Gen: Syntax Node
Gen->>Base: IsRelevantSyntax()
Base-->>Gen: true/false
Gen->>Base: TransformSyntax()
Base-->>Gen: Model
Gen->>Builder: Create builders
Builder->>Builder: Build code
Builder-->>Gen: String
Gen->>Output: AddSource()
Developer Guide
Building from Source
# Clone the repository
git clone https://github.com/FractalDataWorks/smart-generators.git
cd smart-generators
# Build the solution
dotnet build
# Run tests
dotnet test
# Pack NuGet packages
dotnet pack -c Release
Project Dependencies
graph BT
A[SmartGenerators] -->|depends on| R[Roslyn]
B[CodeBuilders] -->|depends on| A
C[TestUtilities] -->|depends on| A
C -->|depends on| B
D[Your Generator] -->|depends on| A
D -->|depends on| B
E[Your Tests] -->|depends on| C
Creating a Custom Builder
public class CustomBuilder : CodeBuilderBase<CustomBuilder>
{
private readonly string _name;
public CustomBuilder(string name) : base()
{
_name = name;
}
public override string Build()
{
var builder = new StringBuilder();
// Add your custom generation logic
builder.AppendLine($"// Custom generated code for {_name}");
return builder.ToString();
}
protected override CustomBuilder ThisBuilder => this;
}
Testing Best Practices
Unit Test Builders
[Fact] public void ClassBuilder_GeneratesCorrectSyntax() { var code = new ClassBuilder("Test") .MakePublic() .Build(); code.ShouldContain("public class Test"); }
Integration Test Generators
[Fact] public void Generator_HandlesComplexScenarios() { var source = LoadTestCase("ComplexScenario.cs"); var output = RunGenerator(source); CompileAndVerify(source, output); }
Use Expectations API
[Fact] public void Generator_ProducesExpectedStructure() { var result = RunGenerator(source); var expectations = ExpectationsFactory.Create(); expectations.ExpectClass("MyClass", c => c .WithModifier("public") .WithMethod("MyMethod")); expectations.Verify(result); }
Debugging Generators
Attach Debugger
#if DEBUG if (!Debugger.IsAttached) { Debugger.Launch(); } #endif
Enable Logging
<PropertyGroup> <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> </PropertyGroup>
Use Diagnostics
context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.Info, Location.None, $"Processing: {model.Name}"));
Contributing
We welcome contributions! Please see our Contributing Guidelines.
Development Process
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Make your changes
- Add or update tests
- Update documentation
- Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
Code Style
- Follow existing patterns and conventions
- Add XML documentation to public APIs
- Include unit tests for new features
- Keep commits focused and atomic
License
This project is licensed under the Apache License 2.0 - 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. |
-
.NETStandard 2.0
- Microsoft.CodeAnalysis.CSharp (>= 4.14.0)
- System.Text.RegularExpressions (>= 4.3.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on FractalDataWorks.SmartGenerators.CodeBuilders:
Package | Downloads |
---|---|
FractalDataWorks.SmartGenerators
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
0.1.5-alpha-g8cae162c25 | 481 | 7/23/2025 |
0.1.4-alpha-g4415be49cc | 276 | 7/21/2025 |
0.1.3-alpha-g2dc2da0077 | 267 | 7/20/2025 |
0.1.2-alpha-gf6ea635473 | 124 | 7/14/2025 |
0.1.1-alpha-gc64e6ae799 | 118 | 7/14/2025 |
0.1.1-alpha-g64f4a16f7b | 111 | 7/14/2025 |