Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/atulin/forged/llms.txt

Use this file to discover all available pages before exploring further.

Forged uses a single marker attribute — [Fake] — to identify the classes and records that should have a strongly-typed faker generated for them. Placing this attribute on a type is all you need to do to opt in to compile-time code generation; there are no constructor parameters to configure and no properties to set.

Attribute declaration

FakeAttribute lives in the Forged.Core namespace. Its declaration is deliberately minimal:
namespace Forged.Core;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
public sealed class FakeAttribute : Attribute
{
}
Although AttributeTargets includes Struct, the Roslyn source generator currently processes only ClassDeclarationSyntax and RecordDeclarationSyntax nodes, so structs are accepted by the compiler but do not yet produce generated output.

Annotating a model

Add [Fake] to any class or record whose instances you want to generate. Mark the properties whose values are mandatory as required:
using Forged.Core;

namespace Forged.Demo;

[Fake]
public class Person
{
    public required Guid   Id          { get; set; }
    public required string FirstName   { get; set; }
    public required string LastName    { get; set; }
    public required string FullName    { get; set; }
    public List<string>?   MiddleNames { get; set; }
    public string?         Nickname    { get; set; }
    public bool            IsActive    { get; set; }
    public DateTime?       DateOfBirth { get; set; }
    public string?         EmailAddress { get; set; }
    public string?         Bio         { get; set; }
}

What happens at build time

1

Generator activation

The Roslyn incremental generator ForgedGenerator activates whenever it finds a type decorated with Forged.Core.FakeAttribute.
2

Property discovery

For each matching type, the generator inspects every member and keeps only public properties that have a setter (SetMethod is not null). Each surviving property is recorded with its name, its fully-qualified type string, and whether it is required.
3

Source emission

A new source file named {Name}Faker.g.cs is added to the compilation. It contains a partial class that inherits Faker<{Name}> and declares one lambda property per discovered property.

Generated faker signature

For a model named Person, the generator emits the following skeleton:
// <auto-generated/>
#nullable enable
using System;
using System.Collections.Generic;
using Forged.Core;
using Forged.Core.Generators;

namespace Forged.Demo;

public partial class PersonFaker : Faker<Person>
{
    // required properties use a non-nullable Func
    public required Func<Forge, IGenerator<Guid>>   Id        { get; init; }
    public required Func<Forge, IGenerator<string>> FirstName { get; init; }
    public required Func<Forge, IGenerator<string>> LastName  { get; init; }
    public required Func<Forge, IGenerator<string>> FullName  { get; init; }

    // optional properties use a nullable Func
    public Func<Forge, IGenerator<List<string>?>>? MiddleNames  { get; init; }
    public Func<Forge, IGenerator<string?>>?       Nickname     { get; init; }
    public Func<Forge, IGenerator<bool>>?          IsActive     { get; init; }
    public Func<Forge, IGenerator<DateTime?>>?     DateOfBirth  { get; init; }
    public Func<Forge, IGenerator<string?>>?       EmailAddress { get; init; }
    public Func<Forge, IGenerator<string?>>?       Bio          { get; init; }

    public PersonFaker(Random? random = null) : base(random) { }

    public override Person Get() { /* ... */ }
}
The generator follows one simple rule for each property:
Property kindGenerated lambda type
requiredpublic required Func<Forge, IGenerator<T>>
optionalpublic Func<Forge, IGenerator<T>>?
Properties without a setter, or properties that are not public, are invisible to the generator and will not appear in the generated faker. This applies to computed properties, init-only properties that the generator cannot see, and any member with a non-public access modifier.

Build docs developers (and LLMs) love