GenDI 26.5.9.165

dotnet add package GenDI --version 26.5.9.165
                    
NuGet\Install-Package GenDI -Version 26.5.9.165
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GenDI" Version="26.5.9.165" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GenDI" Version="26.5.9.165" />
                    
Directory.Packages.props
<PackageReference Include="GenDI" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add GenDI --version 26.5.9.165
                    
#r "nuget: GenDI, 26.5.9.165"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package GenDI@26.5.9.165
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=GenDI&version=26.5.9.165
                    
Install as a Cake Addin
#tool nuget:?package=GenDI&version=26.5.9.165
                    
Install as a Cake Tool

GenDI

Generator-based Dependency Injection for .NET — elegant, fast, AOT-ready

CI/CD Pipeline Deploy Documentation NuGet GenDI NuGet GenDI.SourceGenerator License: MIT Documentation

GenDI is a dependency injection library built on top of C# source generators, providing full compatibility with NativeAOT and trimming. It works as an additional module to Microsoft.Extensions.DependencyInjection, allowing you to register services automatically at compile time — no reflection required.

Say goodbye to constructor bloat

Real-world services accumulate dependencies. With traditional constructor injection this tends to look like this:

// ❌ The "constructor tax" — grows every time a new dependency is added
public class OrderProcessor
{
    private readonly IOrderRepository _orderRepository;
    private readonly IPaymentGateway _paymentGateway;
    private readonly IEmailService _emailService;
    private readonly IInventoryService _inventoryService;
    private readonly ILogger<OrderProcessor> _logger;

    public OrderProcessor(
        IOrderRepository orderRepository,
        IPaymentGateway paymentGateway,
        IEmailService emailService,
        IInventoryService inventoryService,
        ILogger<OrderProcessor> logger)
    {
        _orderRepository = orderRepository;
        _paymentGateway = paymentGateway;
        _emailService = emailService;
        _inventoryService = inventoryService;
        _logger = logger;
    }
}

With GenDI's property injection, the same class becomes clean and self-documenting:

// ✅ Declare what you need — GenDI wires everything at compile time
[Injectable<IOrderProcessor>(ServiceLifetime.Scoped)]
public class OrderProcessor : IOrderProcessor
{
    [Inject] public required IOrderRepository OrderRepository { get; init; }
    [Inject] public required IPaymentGateway PaymentGateway { get; init; }
    [Inject] public required IEmailService EmailService { get; init; }
    [Inject] public required IInventoryService InventoryService { get; init; }
    [Inject] public required ILogger<OrderProcessor> Logger { get; init; }
}

No private fields. No constructor ceremony. No manual wiring. Just declare your dependencies and move on.

Key features and developer benefits

  • Property injection as first-class citizen: use [Inject] on required init-only properties — dependencies read like documentation, not plumbing.
  • Zero boilerplate registration: a single [Injectable] attribute replaces AddScoped<TImpl>() calls scattered across startup files.
  • Readable generated flow: activation is emitted as explicit new + GetRequiredService<T>(), making the wiring transparent and debuggable.
  • Compile-time safety: the C# compiler enforces every required [Inject] property is assigned — you cannot accidentally skip a dependency. Container registration errors (unregistered services) remain runtime exceptions, just like standard DI.
  • Deterministic registration order: Group + Order give you predictable, testable pipeline composition.
  • Attribute-first contract mapping: combine [Injectable], [Injectable<TService>], and [ServiceInjection] with clear intent.
  • Keyed services support: works with both native [FromKeyedServices] and GenDI [Inject(Key = ...)].
  • No runtime scanning cost: compile-time generation eliminates startup overhead from reflection-based scanning.
  • AOT/trimming friendly by design: safe path for teams that need NativeAOT, without forcing this concern for every project.

Installation

dotnet add package GenDI

Usage

Using InjectableAttribute

[ServiceInjection]
public interface IMyService
{
    void Execute();
}

[Injectable(ServiceLifetime.Singleton, Group = 10, Order = 1)]
public class MyService : IMyService
{
    public void Execute() => Console.WriteLine("Service injected!");
}

InjectableAttribute supports:

  • Lifetime (constructor argument, default Transient)
  • Group (optional, default int.MaxValue)
  • Order (optional, default int.MaxValue)
  • ServiceType:
    • [Injectable]null (no explicit contract)
    • [Injectable<TService>]typeof(TService) as explicit contract (additive with [ServiceInjection])
  • Key (optional, default null) for keyed service registration generation

Service registration emission order is:

  1. Group
  2. Order
  3. Service type name (ordinal)

Registering Services

using YourProject.DependencyInjection; // generated by GenDI in the consumer project namespace

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGenDIServices();
var app = builder.Build();
app.Run();

Property Injection with [Inject]

Declare dependencies as required init-only properties and mark them with [Inject]. GenDI generates the activation code — no constructor needed:

[Injectable<IOrderProcessor>(ServiceLifetime.Scoped)]
public class OrderProcessor : IOrderProcessor
{
    [Inject] public required IOrderRepository Repository { get; init; }
    [Inject] public required IPaymentGateway Payment { get; init; }
    [Inject] public required ILogger<OrderProcessor> Logger { get; init; }

    public async Task ProcessAsync(Order order)
    {
        Logger.LogInformation("Processing order {Id}", order.Id);
        await Repository.SaveAsync(order);
        await Payment.ChargeAsync(order);
    }
}

[Inject] also supports optional Key for keyed dependency resolution:

[Inject(Key = "primary")]
public required IMyService Service { get; init; }

Constructor injection is also supported and can use the native DI attribute:

public MyConsumer([FromKeyedServices("primary")] IMyService service) { }

Service Contract Discovery

  • GenDI discovers services from [ServiceInjection] in implemented interfaces and base types.
  • Injectable<TService> is also added to the generated registration list when provided.
  • If no [ServiceInjection] is found in the inheritance/implementation chain, the concrete class is registered as its own service.

Generated Coverage Configuration

By default, generated extensions are included in coverage (no [ExcludeFromCodeCoverage]). You can control this per assembly:

[assembly: GenDI.GenDICoveration(false)] // add [ExcludeFromCodeCoverage] to generated extension

NativeAOT and Trimming (Phase 3)

GenDI includes linker descriptors and validation projects for trimming and NativeAOT scenarios.

Publish with trimming

dotnet publish tests/GenDI.Phase3.TrimValidation.App/GenDI.Phase3.TrimValidation.App.csproj -c Release

Publish with NativeAOT

dotnet publish tests/GenDI.Phase3.NativeAotValidation.App/GenDI.Phase3.NativeAotValidation.App.csproj -c Release -r linux-x64
<linker>
  <assembly fullname="YourAssemblyName">
    <type fullname="YourAssemblyName.DependencyInjection.GenDIServiceCollectionExtensions" preserve="all" />
  </assembly>
</linker>

Documentation Website (Phase 4)

GenDI now ships an English-first Docusaurus documentation website under website/, with a theme aligned to net-mediate.

Local docs development

cd website
npm ci
npm run start

Production docs build

cd website
npm run build

GitHub Pages deployment is handled by .github/workflows/deploy-docs.yml.

Benchmarks (Phase 4)

GenDI now includes a dedicated BenchmarkDotNet project:

  • tests/GenDI.Benchmarks

Primary benchmark focus is startup registration cost:

  • generated registration (AddGenDIServices)
  • reflection-based runtime scanning

Latest published benchmark report:

  • docs/BENCHMARKS.md

Packaging and CI/CD Baseline (Phase 4 / early Phase 5)

The repository includes:

  • versions.props for centralized dynamic versioning
  • pack.props for package metadata and packing defaults
  • .github/workflows/ci-cd.yml and .github/workflows/auto-publish.yml prepared for Sonar/NuGet flows

Local Tooling and Git Hooks

The repository uses local tools and Husky hooks:

  • dotnet-tools.json includes csharpier and husky
  • pre-commit runs:
    • dotnet csharpier format .
    • dotnet test

For fresh clones, src/GenDI/GenDI.csproj runs a pre-restore target that executes dotnet tool restore and dotnet husky install.


Compatibility

Platform / Framework Supported
.NET 8+ YES
NativeAOT YES
Trimming YES
Microsoft.Extensions.DependencyInjection YES

Roadmap

Phase Description Status
1 InjectableAttribute - attribute-based registration Implemented
2 Attribute model + contract discovery + ordering Implemented
3 Advanced NativeAOT support (ILLink.xml, trimming, AOT) Implemented
4 Benchmarks, website/docs, and CI hardening Implemented
5 Official NuGet publication In Progress

See the full plan in ROADMAP.md.


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before opening a pull request.


License

This project is licensed under the MIT License - see LICENSE.md for details.

Product 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 is compatible.  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 is compatible. 
.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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
26.5.9.165 0 5/9/2026
26.5.9.133 0 5/9/2026
26.5.9.22 0 5/9/2026
26.5.8.1428 0 5/8/2026
26.5.8.1272 0 5/8/2026
26.5.8.202 28 5/8/2026
26.5.8.21 42 5/8/2026
26.5.7.897 43 5/7/2026
26.5.7.749 44 5/7/2026