ZeroAlloc.Inject
1.5.0
See the version list below for details.
dotnet add package ZeroAlloc.Inject --version 1.5.0
NuGet\Install-Package ZeroAlloc.Inject -Version 1.5.0
<PackageReference Include="ZeroAlloc.Inject" Version="1.5.0" />
<PackageVersion Include="ZeroAlloc.Inject" Version="1.5.0" />
<PackageReference Include="ZeroAlloc.Inject" />
paket add ZeroAlloc.Inject --version 1.5.0
#r "nuget: ZeroAlloc.Inject, 1.5.0"
#:package ZeroAlloc.Inject@1.5.0
#addin nuget:?package=ZeroAlloc.Inject&version=1.5.0
#tool nuget:?package=ZeroAlloc.Inject&version=1.5.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 | 60 ns / 128 B | 123 ns / 216 B | 56 ns / 88 B | 8 ns / 40 B |
| Resolve scoped (full lifecycle) | 8,225 ns / 304 B | 4,808 ns / 120 B | 3,393 ns / 120 B | 3,025 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).
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
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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. |
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on ZeroAlloc.Inject:
| Package | Downloads |
|---|---|
|
AI.Sentinel
Security monitoring middleware for IChatClient — prompt injection, hallucination, and operational anomaly detection with an intervention engine. |
|
|
ZeroAlloc.Inject.Container
A compile-time DI registration library for .NET. Roslyn source generator wires all service registrations at compile time — no reflection, no scanning. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.7.0 | 93 | 5/18/2026 |
| 1.6.0 | 114 | 5/18/2026 |
| 1.5.0 | 399 | 5/12/2026 |
| 1.4.2 | 285 | 5/12/2026 |
| 1.4.1 | 342 | 5/3/2026 |
| 1.4.0 | 775 | 5/1/2026 |
| 1.3.2 | 855 | 4/29/2026 |
| 1.3.1 | 497 | 4/29/2026 |
| 1.3.0 | 465 | 4/25/2026 |
| 1.2.2 | 123 | 3/20/2026 |
| 1.2.1 | 123 | 3/19/2026 |
| 1.2.0 | 119 | 3/17/2026 |
| 1.1.0 | 125 | 3/16/2026 |
| 0.11.3 | 119 | 3/15/2026 |