ZeroAlloc.Inject.Generator
1.11.3
See the version list below for details.
dotnet add package ZeroAlloc.Inject.Generator --version 1.11.3
NuGet\Install-Package ZeroAlloc.Inject.Generator -Version 1.11.3
<PackageReference Include="ZeroAlloc.Inject.Generator" Version="1.11.3" />
<PackageVersion Include="ZeroAlloc.Inject.Generator" Version="1.11.3" />
<PackageReference Include="ZeroAlloc.Inject.Generator" />
paket add ZeroAlloc.Inject.Generator --version 1.11.3
#r "nuget: ZeroAlloc.Inject.Generator, 1.11.3"
#:package ZeroAlloc.Inject.Generator@1.11.3
#addin nuget:?package=ZeroAlloc.Inject.Generator&version=1.11.3
#tool nuget:?package=ZeroAlloc.Inject.Generator&version=1.11.3
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 | 6,413 ns / 6,944 B | 1,034 ns / 2,664 B | 8 ns / 48 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 | not yet measured³ | 8 ns | N/A³ |
| Create scope | 82 ns / 128 B | 60 ns / 96 B | 58 ns / 88 B | 14 ns / 40 B |
| Resolve scoped, first in a new scope⁴ | 7,181 ns / 304 B | 5,901 ns / 120 B | 4,851 ns / 120 B | 5,216 ns / 120 B |
| Resolve scoped, cached⁵ | 72 ns / 0 B | 19 ns / 0 B | 21 ns / 0 B | 15 ns / 0 B |
¹ Jab is constructor-only. ² Jab decorator wired via factory. ³ Jab 0.10.x requires closed types. The ZA Container now resolves open generics from its own type switch instead of delegating to MS DI, and its benchmark has not been run yet. ⁴ One resolve per fresh scope, so it measures the first, creating resolve; the scope is created outside the measurement. The 120 B is the benchmark's ScopedService itself, a 24 B object plus its 96 B Guid string: ZA and Jab add nothing to it, MS DI adds 184 B. ⁵ The steady state: a service already resolved in a scope created in setup. Every container returns its cached instance without allocating.
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 cached scoped resolves; ZA Standalone is fastest on the first resolve in a new scope. 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, and when every registration is ZA-owned, creating a scope does not build the MS DI fallback provider either. The IEnumerable row above shows the all-Transient registration path; all-Singleton IEnumerable<T> resolutions are now cached: repeat resolutions allocate 0 B in both modes, asserted with AllocationGate in ResolutionAllocationTests.
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–ZAI021 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–ZAI021 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 | No scanning: 8 ns Standalone, ~1 µs Container | 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.
This package has 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.11.5 | 2,741 | 10/18/2026 |
| 1.11.4 | 1,133 | 10/16/2026 |
| 1.11.3 | 639 | 10/15/2026 |
| 1.11.2 | 1,660 | 10/12/2026 |
| 1.11.1 | 1,017 | 10/11/2026 |
| 1.11.0 | 1,149 | 10/10/2026 |
| 1.10.0 | 2,341 | 9/30/2026 |
| 1.9.1 | 102 | 9/30/2026 |
| 1.9.0 | 1,008 | 9/28/2026 |
| 1.8.0 | 1,392 | 9/25/2026 |
| 1.7.6 | 2,166 | 9/20/2026 |
| 1.7.5 | 219 | 9/20/2026 |
| 1.7.4 | 183 | 9/19/2026 |
| 1.7.3 | 3,364 | 8/12/2026 |
| 1.7.2 | 1,369 | 7/25/2026 |
| 1.7.1 | 4,218 | 5/28/2026 |
| 1.7.0 | 709 | 5/18/2026 |
| 1.6.0 | 226 | 5/18/2026 |
| 1.5.0 | 576 | 5/12/2026 |
| 1.4.2 | 313 | 5/12/2026 |