Skip to content

RegisterClosedOverImplementationsOfAttribute

NexusLabs.Needlr.Generators

RegisterClosedOverImplementationsOfAttribute Class

Marks an open generic \<em>composition\</em> class so that the source generator registers a closed instance of it for \<strong>each\</strong> discovered concrete implementation of a designated open generic interface, exposed as a designated non-generic (or less-generic) facade service type.

public sealed class RegisterClosedOverImplementationsOfAttribute : System.Attribute

Inheritance System.Object 🡒 System.Attribute 🡒 RegisterClosedOverImplementationsOfAttribute

Example

// Auto-discovered today: concrete, closed, unattributed.
public interface IFooDefinition<TData> where TData : class
{
    string Discriminator { get; }
}

public sealed class AlphaFoo : IFooDefinition<AlphaData> { /* ... */ }
public sealed class BetaFoo  : IFooDefinition<BetaData>  { /* ... */ }

// Non-generic facade consumed as IEnumerable<IFoo>.
public interface IFoo { string Discriminator { get; } }

// Reusable composition closed per discovered TData and exposed as IFoo.
[RegisterClosedOverImplementationsOf(typeof(IFooDefinition<>), As = typeof(IFoo))]
public sealed class FooCore<TData> : IFoo where TData : class
{
    public FooCore(IFooDefinition<TData> definition, IFooStore<TData> store) { /* ... */ }
    public string Discriminator => /* delegates to definition */ "";
}

// Generator emits, per discovered implementation:
// services.AddSingleton<IFoo>(sp => new FooCore<AlphaData>(
//     sp.GetRequiredService<IFooDefinition<AlphaData>>(),
//     sp.GetRequiredService<IFooStore<AlphaData>>()));
// services.AddSingleton<IFoo>(sp => new FooCore<BetaData>( ... ));

Remarks

This is a source-generation only feature. It requires the NexusLabs.Needlr.Generators package and has no effect when using reflection-based registration.

Use this attribute to keep a "compose-and-expose" pattern on the source-generation path instead of hand-maintaining one registration line per type argument (which silently drifts) or falling back to runtime reflection (which is AOT/trimming hostile). For every concrete closed implementation of the designated open generic interface that the generator discovers, it closes this composition class over the same type argument(s) and registers it as the service type named by As, resolving the composition's constructor dependencies from the service provider.

The annotated class must: - Be an open generic class whose type-parameter arity matches the open generic interface. - Implement the service type specified by As. - Have a single public constructor whose parameters are all resolvable from the service provider.

A discovered type argument that does not satisfy the composition class's generic constraints is skipped with a build diagnostic (NDLRGEN038) rather than producing a runtime failure.

Constructors

RegisterClosedOverImplementationsOfAttribute(Type) Constructor

Initializes a new instance of the RegisterClosedOverImplementationsOfAttribute class.

public RegisterClosedOverImplementationsOfAttribute(System.Type sourceOpenGenericInterface);

Parameters

sourceOpenGenericInterface System.Type

The open generic interface whose concrete closed implementations drive registration (e.g., typeof(IFooDefinition<>)). Must be an open generic interface.

Properties

RegisterClosedOverImplementationsOfAttribute.As Property

Gets or sets the service type that each closed composition is registered as (e.g., typeof(IFoo)). Must be a type implemented by the annotated composition class.

public System.Type? As { get; set; }

Property Value

System.Type

RegisterClosedOverImplementationsOfAttribute.Lifetime Property

Gets or sets the lifetime each closed composition registration is given. Defaults to Singleton.

public NexusLabs.Needlr.Generators.InjectableLifetime Lifetime { get; set; }

Property Value

InjectableLifetime

RegisterClosedOverImplementationsOfAttribute.SourceOpenGenericInterface Property

Gets the open generic interface whose concrete closed implementations drive registration.

public System.Type SourceOpenGenericInterface { get; }

Property Value

System.Type