IL.AttributeBasedDI
2.6.1
dotnet add package IL.AttributeBasedDI --version 2.6.1
NuGet\Install-Package IL.AttributeBasedDI -Version 2.6.1
<PackageReference Include="IL.AttributeBasedDI" Version="2.6.1" />
<PackageVersion Include="IL.AttributeBasedDI" Version="2.6.1" />
<PackageReference Include="IL.AttributeBasedDI" />
paket add IL.AttributeBasedDI --version 2.6.1
#r "nuget: IL.AttributeBasedDI, 2.6.1"
#:package IL.AttributeBasedDI@2.6.1
#addin nuget:?package=IL.AttributeBasedDI&version=2.6.1
#tool nuget:?package=IL.AttributeBasedDI&version=2.6.1
IL.AttributeBasedDI
Control dependencies and decorators via custom attributes - extends Microsoft.Extensions.DependencyInjection.
Note: Starting from version 2.0.0, only .NET 8 or higher is supported.
How to Use
- Reference
IL.AttributeBasedDIin your project. - Use the registration extensions provided by the library to activate functionality:
services.AddServiceAttributeBasedDependencyInjection()forIServiceCollection.builder.AddServiceAttributeBasedDependencyInjection()forWebApplicationBuilder.
- Optionally, filter assemblies for reflection search using the
assemblyFiltersparameter (e.g.,"MyProject.*").
Attributes
[Service]
Use this attribute to automatically register classes in the DI container.
Parameters:
- Lifetime: Defines the service registration lifetime (
Singleton,Scoped, orTransient). - ServiceType: Specifies the service type for DI registration. If
null, the service type is automatically resolved:- From the first interface the class implements, or
- The class itself if no interfaces are implemented.
- Key (
.NET 8+): Specifies a key for keyed service registration. - Feature (optional): Specifies a feature flag to conditionally register the service.
[ServiceWithOptions]
Use this attribute to automatically register classes with options from configuration in the DI container.
Parameters:
- Lifetime: Defines the service registration lifetime (
Singleton,Scoped, orTransient). - ServiceType: Specifies the service type for DI registration. If
null, the service type is automatically resolved:- From the first interface the class implements, or
- The class itself if no interfaces are implemented.
- Key (
.NET 8+): Specifies a key for keyed service registration. - Feature (optional): Specifies a feature flag to conditionally register the service.
How it works
The ServiceWithOptions attribute requires a generic type that implements the IServiceConfiguration interface. This interface has a static abstract property ConfigurationPath that defines the path to the configuration section in appsettings.json.
Example
appsettings.json
{
"AppSettings": {
"Test": {
"Option1": "test12345"
}
}
}
ServiceTestOptions.cs
public class ServiceTestOptions : IServiceConfiguration
{
public static string ConfigurationPath => "AppSettings:Test";
public string Option1 { get; set; } = "test123";
}
TestServiceWithOptions.cs
[ServiceWithOptions<ServiceTestOptions>]
public class TestServiceWithOptions
{
private readonly ServiceTestOptions _serviceConfiguration;
public TestServiceWithOptions(IOptions<ServiceTestOptions> options)
{
_serviceConfiguration = options.Value;
}
public string GetOption1Value() => _serviceConfiguration.Option1;
}
[Decorator]
Use this attribute to automatically register decorators for specific services.
Parameters:
- ServiceType: Specifies the service type to decorate. If
null, the service type is automatically resolved from the first interface the class implements. - DecorationOrder: Defines the order of decoration. Lower values are closer to the original implementation in the execution chain.
- Key (
.NET 8+): Specifies a key for keyed decorator registration. - Feature (optional): Specifies a feature flag to conditionally register the decorator.
- TreatOpenGenericsAsWildcard (optional,
bool): When set totrue, the decorator will treat open generic service types as a wildcard, allowing it to decorate any closed generic implementation of that service.
Examples
Basic Usage
IService resolves to:
DecoratorA- Wrapping
SampleService
- Wrapping
[Service]
class SampleService : IService {}
[Decorator]
class DecoratorA : IService {}
IService resolves to:
DecoratorBWrapping DecoratorAWrapping SampleService
[Service(serviceType: typeof(IService), lifetime: Lifetime.Singleton)]
class SampleService : IService {}
[Decorator(serviceType: typeof(IService), decorationOrder: 1)]
class DecoratorA : IService
{
public DecoratorA(IService service)
{
// `service` here is actually `SampleService`
}
}
[Decorator(serviceType: typeof(IService), decorationOrder: 2)]
class DecoratorB : IService
{
public DecoratorB(IService service)
{
// `service` here is actually `DecoratorA`
}
}
.NET 8 Keyed Services
[Service(Key = "randomKey")]
class SampleServiceDefault : IService {}
[Service(Key = "testKey")]
class SampleService : IService {}
[Decorator(Key = "testKey")]
class DecoratorA : IService {}
public class Test
{
public Test(
[FromKeyedServices("randomKey")] IService randomSvc,
[FromKeyedServices("testKey")] IService svc)
{
// `randomSvc` resolves to `SampleServiceDefault`
// `svc` resolves to `DecoratorA` wrapping `SampleService`
}
}
Feature Flags
Note: Starting from version 2.0.0, you can conditionally register services and decorators based on feature flags.
[Flags]
public enum Features
{
None = 0,
FeatureA = 1 << 0,
FeatureB = 1 << 1,
FeatureC = 1 << 2
}
[Service<Features>(Feature = Features.FeatureA)]
class FeatureAService : IService {}
[Service<Features>(Feature = Features.FeatureB)]
class FeatureBService : IService {}
[Decorator<Features>(Feature = Features.FeatureA)]
class FeatureADecorator : IService {}
[Decorator<Features>(Feature = Features.FeatureB)]
class FeatureBDecorator : IService {}
var builder = WebApplication.CreateBuilder(args);
// single feature type
builder.AddServiceAttributeBasedDependencyInjection(configuration,
options => options.AddFeature(Features.FeatureA | Features.FeatureC)
);
//or multiple feature types
builder.AddServiceAttributeBasedDependencyInjection(configuration,
options => {
options.AddFeature(Features.FeatureA | Features.FeatureC);
options.AddFeature(AnotherFeaturesEnum.FeatureA | AnotherFeaturesEnum.FeatureC);
}
);
// AddFeature will merge features of same type if called multiple times resulting same as bit operator invariant (FeatureA | FeatureC)
builder.AddServiceAttributeBasedDependencyInjection(configuration,
options => {
options.AddFeature(Features.FeatureA);
options.AddFeature(Features.FeatureC);
options.AddFeature(AnotherFeaturesEnum.FeatureA);
options.AddFeature(AnotherFeaturesEnum.FeatureC);
}
);
or appsettings.json based:
{
"DIFeatureFlags": {
"Features": ["FeatureA", "FeatureC"]
}
}
and then you have to specify key/type mappings in options:
builder.AddServiceAttributeBasedDependencyInjection(configuration,
options => options.SetFeaturesFromConfig(
new Dictionary<string, Type>
{
{ nameof(Features), typeof(Features) }
}
);
);
// you can also specify custom root object key in appsettings.json instead of "DIFeatureFlags"
builder.AddServiceAttributeBasedDependencyInjection(configuration,
options => options.SetFeaturesFromConfig(
new Dictionary<string, Type>
{
{ nameof(Features), typeof(Features) }
},
"CustomRootObjectKeyInsteadOfDIFeatureFlags"
);
);
Migration to Version 2.0.0
Starting from version 2.0.0, only .NET 8 or higher is supported. If you're upgrading from an earlier version, ensure your project targets .NET 8 or higher.
| 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 was computed. 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. |
-
net8.0
- IL.Misc (>= 1.4.1)
- Microsoft.Extensions.DependencyInjection (>= 8.0.1)
- Microsoft.Extensions.Options (>= 8.0.2)
-
net9.0
- IL.Misc (>= 1.4.1)
- Microsoft.Extensions.DependencyInjection (>= 9.0.10)
- Microsoft.Extensions.Options (>= 9.0.10)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on IL.AttributeBasedDI:
| Package | Downloads |
|---|---|
|
IL.UmbracoSearch
A comprehensive search solution for Umbraco, supporting both Lucene and Azure Search, with extensible indexing and flexible search parameters. |
|
|
IL.AttributeBasedDI.Visualizer
Extension for IL.AttributeBasedDI |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.6.1 | 394 | 11/7/2025 |
| 2.6.0 | 532 | 10/30/2025 |
| 2.5.3 | 1,235 | 7/30/2025 |
| 2.5.2 | 939 | 6/10/2025 |
| 2.5.1 | 151 | 5/31/2025 |
| 2.5.0 | 314 | 5/20/2025 |
| 2.4.5 | 300 | 5/7/2025 |
| 2.4.4 | 218 | 5/7/2025 |
| 2.4.3 | 208 | 5/6/2025 |
| 2.4.2 | 201 | 5/6/2025 |
| 2.4.1 | 210 | 5/6/2025 |
| 2.4.0 | 216 | 5/6/2025 |
| 2.3.3 | 212 | 5/5/2025 |
| 2.3.2 | 235 | 4/21/2025 |
| 2.3.1 | 209 | 4/21/2025 |
| 2.3.0 | 207 | 4/21/2025 |
| 2.2.2 | 273 | 4/8/2025 |
| 2.2.1 | 250 | 3/27/2025 |
| 2.2.0 | 311 | 3/17/2025 |
| 2.1.0 | 414 | 2/26/2025 |
| 2.0.2 | 176 | 2/26/2025 |
| 2.0.1 | 164 | 2/26/2025 |
| 2.0.0 | 153 | 2/25/2025 |
| 1.7.0 | 145 | 2/25/2025 |
| 1.6.0 | 1,688 | 9/27/2024 |
| 1.5.1 | 696 | 9/12/2024 |
| 1.5.0 | 267 | 9/5/2024 |
| 1.4.0 | 173 | 9/1/2024 |
| 1.3.2 | 354 | 7/17/2024 |
| 1.3.0 | 427 | 5/6/2024 |
| 1.2.0 | 410 | 3/3/2024 |
| 1.1.3 | 196 | 3/3/2024 |
| 1.0.3 | 545 | 2/22/2024 |
| 1.0.2 | 1,844 | 7/31/2023 |
| 1.0.1 | 245 | 7/29/2023 |
| 1.0.0 | 283 | 7/17/2023 |