GenDI 26.5.9.165
dotnet add package GenDI --version 26.5.9.165
NuGet\Install-Package GenDI -Version 26.5.9.165
<PackageReference Include="GenDI" Version="26.5.9.165" />
<PackageVersion Include="GenDI" Version="26.5.9.165" />
<PackageReference Include="GenDI" />
paket add GenDI --version 26.5.9.165
#r "nuget: GenDI, 26.5.9.165"
#:package GenDI@26.5.9.165
#addin nuget:?package=GenDI&version=26.5.9.165
#tool nuget:?package=GenDI&version=26.5.9.165
GenDI
Generator-based Dependency Injection for .NET — elegant, fast, AOT-ready
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]onrequiredinit-only properties — dependencies read like documentation, not plumbing. - Zero boilerplate registration: a single
[Injectable]attribute replacesAddScoped<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+Ordergive 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, defaultTransient)Group(optional, defaultint.MaxValue)Order(optional, defaultint.MaxValue)ServiceType:[Injectable]→null(no explicit contract)[Injectable<TService>]→typeof(TService)as explicit contract (additive with[ServiceInjection])
Key(optional, defaultnull) for keyed service registration generation
Service registration emission order is:
GroupOrder- 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
ILLink descriptor sample
<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.propsfor centralized dynamic versioningpack.propsfor package metadata and packing defaults.github/workflows/ci-cd.ymland.github/workflows/auto-publish.ymlprepared for Sonar/NuGet flows
Local Tooling and Git Hooks
The repository uses local tools and Husky hooks:
dotnet-tools.jsonincludescsharpierandhusky- 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 | 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 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. |
-
.NETStandard 2.0
-
.NETStandard 2.1
-
net10.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 |
|---|---|---|
| 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 |