IL.AttributeBasedDI 2.7.1.1

dotnet add package IL.AttributeBasedDI --version 2.7.1.1
                    
NuGet\Install-Package IL.AttributeBasedDI -Version 2.7.1.1
                    
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.7.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="IL.AttributeBasedDI" Version="2.7.1.1" />
                    
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.7.1.1
                    
#r "nuget: IL.AttributeBasedDI, 2.7.1.1"
                    
#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.7.1.1
                    
#: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.7.1.1
                    
Install as a Cake Addin
#tool nuget:?package=IL.AttributeBasedDI&version=2.7.1.1
                    
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.

Feature-flag support in this library works as follows:

  • Feature enums used with [Service<TFeatureFlag>] / [Decorator<TFeatureFlag>] must be marked with [Flags].
  • You can enable multiple feature enum types in the same registration call.
  • AddFeature(...) merges repeated calls for the same enum type using bitwise OR.
  • If an attribute declares multiple flags (e.g., FeatureA | FeatureC), registration is enabled when at least one of those flags is active.
[Flags]
public enum SearchOptions
{
    None = 0,
    Azure = 1 << 0,
    Elastic = 1 << 1
}

[Flags]
public enum AnotherOptionsEnum
{
    None = 0,
    FeatureX = 1 << 0,
    FeatureY = 1 << 1
}

[Service<SearchOptions>(Feature = SearchOptions.Azure)]
class AzureSearchService : ISearchService {}

[Service<AnotherOptionsEnum>(Feature = AnotherOptionsEnum.FeatureX)]
class FeatureXService : IFeatureService {}

Enable flags in code:

var builder = WebApplication.CreateBuilder(args);

builder.AddServiceAttributeBasedDependencyInjection(options =>
{
    options.AddFeature(SearchOptions.Azure);
    options.AddFeature(AnotherOptionsEnum.FeatureX);

    // same enum type is merged
    options.AddFeature(SearchOptions.Elastic);
});

Enable flags from appsettings (including multiple enum types):

{
  "DIFeatureFlags": {
    "SearchOptions": ["Azure"],
    "AnotherOptionsEnum": ["FeatureX"]
  }
}
builder.AddServiceAttributeBasedDependencyInjection(options =>
{
    options.SetFeaturesFromConfig(new Dictionary<string, Type>
    {
        { nameof(SearchOptions), typeof(SearchOptions) },
        { nameof(AnotherOptionsEnum), typeof(AnotherOptionsEnum) }
    });
});

// custom root section (instead of "DIFeatureFlags")
builder.AddServiceAttributeBasedDependencyInjection(options =>
{
    options.SetFeaturesFromConfig(
        new Dictionary<string, Type>
        {
            { nameof(SearchOptions), typeof(SearchOptions) },
            { nameof(AnotherOptionsEnum), typeof(AnotherOptionsEnum) }
        },
        "CustomFeatureFlagsRoot");
});

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 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. 
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.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.7.1.1 48 3/14/2026
2.7.0.1 892 1/5/2026
2.6.1 699 11/7/2025
2.6.0 580 10/30/2025
2.5.3 1,364 7/30/2025
2.5.2 1,164 6/10/2025
2.5.1 189 5/31/2025
2.5.0 357 5/20/2025
2.4.5 342 5/7/2025
2.4.4 256 5/7/2025
2.4.3 241 5/6/2025
2.4.2 243 5/6/2025
2.4.1 257 5/6/2025
2.4.0 257 5/6/2025
2.3.3 254 5/5/2025
2.3.2 272 4/21/2025
2.3.1 247 4/21/2025
2.3.0 247 4/21/2025
2.2.2 317 4/8/2025
2.2.1 296 3/27/2025
Loading failed