ZeroAlloc.Inject.Generator
1.6.0
See the version list below for details.
dotnet add package ZeroAlloc.Inject.Generator --version 1.6.0
NuGet\Install-Package ZeroAlloc.Inject.Generator -Version 1.6.0
<PackageReference Include="ZeroAlloc.Inject.Generator" Version="1.6.0" />
<PackageVersion Include="ZeroAlloc.Inject.Generator" Version="1.6.0" />
<PackageReference Include="ZeroAlloc.Inject.Generator" />
paket add ZeroAlloc.Inject.Generator --version 1.6.0
#r "nuget: ZeroAlloc.Inject.Generator, 1.6.0"
#:package ZeroAlloc.Inject.Generator@1.6.0
#addin nuget:?package=ZeroAlloc.Inject.Generator&version=1.6.0
#tool nuget:?package=ZeroAlloc.Inject.Generator&version=1.6.0
ZeroAlloc.Inject
Compile-time DI registration for .NET. A Roslyn source generator that auto-discovers services via attributes and generates IServiceCollection extension methods and a Native AOT-compatible IServiceProvider. No reflection, no runtime scanning — misconfigured dependencies surface as build errors before the application ever starts.
Install
For ASP.NET Core and Generic Host projects (MS DI runtime):
dotnet add package ZeroAlloc.Inject
dotnet add package ZeroAlloc.Inject.Generator
For standalone or hybrid container mode (no separate attribute package needed):
dotnet add package ZeroAlloc.Inject.Container
ZeroAlloc.Inject.Container bundles the generator, attributes, and the container base classes in a single package.
30-Second Example
// 1. Annotate your service with a lifetime attribute
using ZeroAlloc.Inject;
[Transient] // registered as IOrderService + OrderService
public class OrderService : IOrderService
{
private readonly IProductRepository _repo;
public OrderService(IProductRepository repo) => _repo = repo;
public Order PlaceOrder(int productId) => /* ... */
}
// 2. Register all attributed services in one generated call
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMyAppServices(); // generated at compile time from assembly name
// 3. Resolve the service — or let the framework inject it for you
var app = builder.Build();
var service = app.Services.GetRequiredService<IOrderService>();
The generator derives the method name from the assembly name: MyApp → AddMyAppServices(), MyApp.Domain → AddMyAppDomainServices(). Override with [assembly: ZeroAllocInject("AddDomainServices")].
Performance
.NET 10 host / .NET 9.0.15 runtime, BenchmarkDotNet v0.15.8, Intel Core i9-12900HK. Compared against MS DI (reflection) and Jab (the other source-gen DI library).
| Scenario | MS DI | ZA Container | ZA Standalone | Jab |
|---|---|---|---|---|
| Startup / registration | 138 ns / 528 B | 10,998 ns / 11,192 B | 4 ns / 32 B | 8 ns / 40 B |
| Transient (1 dep) | 31 ns | 27 ns | 24 ns | 47 ns |
| Transient (1 property dep) | 44 ns | 27 ns | 22 ns | N/A¹ |
| Decorated transient | 44 ns | 21 ns | 22 ns | 29 ns² |
IEnumerable<T> (3 impls) |
68 ns | 75 ns | 82 ns | 151 ns |
| Open generic (closed type) | 14 ns | (via MS DI) | 8 ns | N/A³ |
| Create scope | 82 ns / 128 B | 60 ns / 96 B | 58 ns / 88 B | 14 ns / 40 B |
| Resolve scoped (full lifecycle) | 7,181 ns / 304 B | 5,901 ns / 120 B | 4,851 ns / 120 B | 5,216 ns / 120 B |
¹ Jab is constructor-only. ² Jab decorator wired via factory. ³ Jab 0.10.x requires closed types.
ZA wins where the generator's domain knowledge matters: property injection (2× MS DI), decorators (2.1× MS DI), open generics (1.8× MS DI). Jab wins on scope creation and pure scoped lifecycle. MS DI wins on IEnumerable<T> (its cached multi-registration enumeration is excellent).
In v1.6 the ZA Container scope creation dropped 50% on allocation (216 B → 96 B) and 2× faster — the MS DI fallback scope is no longer eagerly created; it materializes on first fallback resolution. For ZA-owned registrations (the common case), it never materializes at all. The IEnumerable row above shows the all-Transient registration path; all-Singleton IEnumerable<T> resolutions are now cached (0 B on subsequent calls — verified by tests).
Full methodology, all scenarios, and analysis: docs/performance.md.
Features
- Compile-time registration —
[Transient],[Scoped],[Singleton]attributes; the generator emits allIServiceCollection.Add*calls - Zero reflection — generated code uses direct
new ClassName(...)constructor calls andtypeof(T)type switches - Native AOT compatible — standalone container is 100% AOT-safe including open generics
- Three container modes — MS DI extension method, Hybrid (wraps MS DI), and Standalone (no runtime MS DI dependency)
- Decorators —
[Decorator]/[DecoratorOf]with ordering, conditional application (WhenRegistered), and optional dependencies - Keyed services —
Key = "redis"on any lifetime attribute (.NET 8+) - Open generics — single attribute covers all closed forms; standalone mode enumerates closed usages at compile time
- Compile-time diagnostics — ZAI001–ZAI018 reported as build errors/warnings, including circular dependency detection
TryAddby default — prevents duplicate registrations; opt in toAllowMultiple = trueforIHostedServicescenarios- Multi-assembly — each assembly generates its own extension method; call them in sequence at the composition root
Documentation
| Page | Description |
|---|---|
| Getting Started | Install, annotate services, call the generated method |
| Service Registration | Lifetime attributes, As, keyed services, open generics |
| Container Modes | MS DI Extension, Hybrid, and Standalone — trade-offs and setup |
| Decorators | [Decorator], [DecoratorOf], ordering, conditional decorators |
| Native AOT | Trimmer safety, publishing, ASP.NET Core AOT setup |
| Advanced Patterns | Multi-assembly, constructor disambiguation, collection injection |
| Compiler Diagnostics | ZAI001–ZAI018 reference with triggers and fixes |
| Performance | Full benchmark tables and analysis |
| Testing | Unit testing without the container, integration test setup per mode |
How It Compares to Scrutor
| ZeroAlloc.Inject | Scrutor | |
|---|---|---|
| Discovery | Compile-time source gen | Runtime assembly scanning |
| Reflection | None | Yes |
| Native AOT | ✅ Standalone mode | ❌ |
| Startup cost | Zero | Scales with assembly size |
| IDE support | Compile errors + warnings | Runtime exceptions |
| Configuration | Attributes on classes | Fluent API in Program.cs |
Requirements
- .NET 8.0, .NET 9.0, or .NET 10.0
- C# 12+
License
MIT
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on ZeroAlloc.Inject.Generator:
| Package | Downloads |
|---|---|
|
AI.Sentinel
Security monitoring middleware for IChatClient — prompt injection, hallucination, and operational anomaly detection with an intervention engine. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.7.0 | 58 | 5/18/2026 |
| 1.6.0 | 141 | 5/18/2026 |
| 1.5.0 | 370 | 5/12/2026 |
| 1.4.2 | 272 | 5/12/2026 |
| 1.4.1 | 297 | 5/3/2026 |
| 1.4.0 | 775 | 5/1/2026 |
| 1.3.2 | 831 | 4/29/2026 |
| 1.3.1 | 473 | 4/29/2026 |
| 1.3.0 | 441 | 4/25/2026 |
| 1.2.2 | 104 | 3/20/2026 |
| 1.2.1 | 99 | 3/19/2026 |
| 1.2.0 | 99 | 3/17/2026 |
| 1.1.0 | 103 | 3/16/2026 |
| 0.11.3 | 102 | 3/15/2026 |