AttributedDI 1.0.1
dotnet add package AttributedDI --version 1.0.1
NuGet\Install-Package AttributedDI -Version 1.0.1
<PackageReference Include="AttributedDI" Version="1.0.1" />
<PackageVersion Include="AttributedDI" Version="1.0.1" />
<PackageReference Include="AttributedDI" />
paket add AttributedDI --version 1.0.1
#r "nuget: AttributedDI, 1.0.1"
#:package AttributedDI@1.0.1
#addin nuget:?package=AttributedDI&version=1.0.1
#tool nuget:?package=AttributedDI&version=1.0.1
AttributedDI
Keep DI registration close to your services.
AttributedDI lets you mark services with simple attributes, generates interfaces from your
implementations, and wires everything with the equivalent
services.AddTransient/Scoped/Singleton(...) calls at compile time. Registrations live
next to the types they describe, and the generator writes the wiring for you (no runtime
reflection, AOT friendly).
Why
If you've ever shipped a bug because you forgot to register a service in Program.cs,
or spent time debating lifetimes while staring at a giant registration list, this is for you.
I built AttributedDI after repeatedly:
- forgetting to add new services in
Program.cs, - second-guessing the correct lifetime for each service, and
- refactoring
Program.csas the list grew past a dozen registrations.
Manual DI registration scales poorly as projects grow, and runtime scanning is slow and unfriendly to trimming/AOT. AttributedDI keeps registration colocated with the type, and its interface generation helps you introduce abstractions without the usual manual churn. It produces normal, readable registration code during build.
Features
- Interface generation from concrete types (with optional auto-registration).
- Attribute-driven registration for self, implemented interfaces, or a specific service type.
- Compile-time source generation (no runtime reflection scan).
- Keyed registrations when you pass a key to registration attributes.
- Optional interface generation from concrete types.
- Customizable extension class/method names.
- Optional aggregate
AddAttributedDi()to register across references.
Installation
Add the package to any project that defines services:
dotnet add package AttributedDI
The source generator is included automatically with the package reference.
Quick start
Annotate services and call the generated extension method.
using AttributedDI;
using Microsoft.Extensions.DependencyInjection;
namespace MyApp;
public interface IClock
{
DateTime UtcNow { get; }
}
[Singleton]
[RegisterAs<IClock>]
public sealed class SystemClock : IClock
{
public DateTime UtcNow => DateTime.UtcNow;
}
[Scoped]
[RegisterAsSelf]
public sealed class Session
{
}
AttributedDI can also generate an interface for you and register against it in one step:
[RegisterAsGeneratedInterface]
public sealed partial class MetricsSink
{
public void Write(string name, double value) { }
[ExcludeInterfaceMember]
public string DebugOnly => "local";
}
At build time, AttributedDI generates an extension method named Add{AssemblyName} on
{AssemblyName}ServiceCollectionExtensions (names are sanitized into valid identifiers).
Use it in startup:
var services = new ServiceCollection();
services.AddMyApp();
Registration options
RegisterAsSelfregisters the type as itself.RegisterAsImplementedInterfacesregisters the type against all implemented interfaces.RegisterAs<TService>registers the type against a specific service type.- Apply
Transient,Scoped, orSingletonto pick a lifetime (default is transient). - Pass a key to any registration attribute to generate keyed registrations.
Example with a keyed registration:
[Singleton]
[RegisterAs<IGateway>("primary")]
public sealed class PrimaryGateway : IGateway
{
}
Interface generation
Generate an interface from a concrete type:
[GenerateInterface]
public sealed partial class WeatherClient
{
public Task<string> GetAsync(string city, CancellationToken ct) => Task.FromResult("ok");
}
Generate an interface and register against it in one step:
[RegisterAsGeneratedInterface]
public sealed partial class MetricsSink
{
public void Write(string name, double value) { }
[ExcludeInterfaceMember]
public string DebugOnly => "local";
}
Both [GenerateInterface] and [RegisterAsGeneratedInterface] require a non-nested partial class or struct.
For edge cases and exclusions, see docs/interface-generation-exceptions.md.
Customize the generated extension
If you want stable, explicit names, apply the assembly-level attribute:
using AttributedDI;
[assembly: ServiceCollectionExtension(
extensionClassName: "DependencyInjectionExtensions",
methodName: "AddMyServices",
extensionNamespace: "MyApp")]
Then call:
services.AddMyServices();
Aggregate registration across references
If you have multiple projects that each define services, you can generate a single
AddAttributedDi() method in the top-level project that calls all of their generated
extension methods.
Typical setup:
- Install
AttributedDIin each downstream project that defines services. - Mark services with registration attributes in those downstream projects.
- Reference those downstream projects from your upstream (composition root) project.
- Enable aggregate generation in the upstream project.
Enable it in the upstream project file:
<PropertyGroup>
<GenerateAttributedDIExtensions>true</GenerateAttributedDIExtensions>
</PropertyGroup>
Then call:
services.AddAttributedDi();
License
MIT. See LICENSE.
| 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
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0 && < 11.0.0)
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0 && < 11.0.0)
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0 && < 11.0.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 |
|---|---|---|
| 1.0.1 | 31 | 1/27/2026 |
| 1.0.0 | 44 | 1/26/2026 |
| 1.0.0-alpha001 | 40 | 1/25/2026 |