IL.AttributeBasedDI 2.5.3

dotnet add package IL.AttributeBasedDI --version 2.5.3
                    
NuGet\Install-Package IL.AttributeBasedDI -Version 2.5.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="IL.AttributeBasedDI" Version="2.5.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="IL.AttributeBasedDI" Version="2.5.3" />
                    
Directory.Packages.props
<PackageReference Include="IL.AttributeBasedDI" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add IL.AttributeBasedDI --version 2.5.3
                    
#r "nuget: IL.AttributeBasedDI, 2.5.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package IL.AttributeBasedDI@2.5.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=IL.AttributeBasedDI&version=2.5.3
                    
Install as a Cake Addin
#tool nuget:?package=IL.AttributeBasedDI&version=2.5.3
                    
Install as a Cake Tool

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

  1. Reference IL.AttributeBasedDI in your project.
  2. Use the registration extensions provided by the library to activate functionality:
    • services.AddServiceAttributeBasedDependencyInjection() for IServiceCollection.
    • builder.AddServiceAttributeBasedDependencyInjection() for WebApplicationBuilder.
  3. Optionally, filter assemblies for reflection search using the assemblyFilters parameter (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, or Transient).
  • 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, or Transient).
  • 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 to true, 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
[Service]
class SampleService : IService {}

[Decorator]
class DecoratorA : IService {}

IService resolves to:

  • DecoratorB
    • Wrapping DecoratorA
      • Wrapping 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on IL.AttributeBasedDI:

Package Downloads
IL.AttributeBasedDI.Visualizer

Extension for IL.AttributeBasedDI

IL.UmbracoSearch

A comprehensive search solution for Umbraco, supporting both Lucene and Azure Search, with extensible indexing and flexible search parameters.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.5.3 173 7/30/2025
2.5.2 458 6/10/2025
2.5.1 104 5/31/2025
2.5.0 265 5/20/2025
2.4.5 251 5/7/2025
2.4.4 170 5/7/2025
2.4.3 161 5/6/2025
2.4.2 154 5/6/2025
2.4.1 158 5/6/2025
2.4.0 165 5/6/2025
2.3.3 170 5/5/2025
2.3.2 191 4/21/2025
2.3.1 166 4/21/2025
2.3.0 164 4/21/2025
2.2.2 228 4/8/2025
2.2.1 205 3/27/2025
2.2.0 273 3/17/2025
2.1.0 361 2/26/2025
2.0.2 136 2/26/2025
2.0.1 124 2/26/2025
2.0.0 113 2/25/2025
1.7.0 107 2/25/2025
1.6.0 1,596 9/27/2024
1.5.1 656 9/12/2024
1.5.0 221 9/5/2024
1.4.0 135 9/1/2024
1.3.2 316 7/17/2024
1.3.0 400 5/6/2024
1.2.0 371 3/3/2024
1.1.3 158 3/3/2024
1.0.3 491 2/22/2024
1.0.2 1,625 7/31/2023
1.0.1 208 7/29/2023
1.0.0 245 7/17/2023