Skip to content

Repository files navigation

Immediate.Injections

NuGetGitHub releaseGitHub licenseGitHub issuesGitHub issues-closedGitHub ActionsCoverage Status

Immediate.Injections is a support package for Microsoft.Extensions.DependencyInjection which allows declaring registrations through attributes. This package supports multiple registration strategies, duplicate-handling strategies, tagging, and much more.

Installation

dotnet add package Immediate.Injections

Basic Usage

Declaring a registration

Apply one of the three lifetime attributes to a class or record:

[RegisterSingleton]publicclassMyService;[RegisterScoped]publicclassMyScopedService;[RegisterTransient]publicclassMyTransientService<T>;

By default (when no RegistrationStrategy is set at the attribute or assembly level), a class is registered as itself. Generic classes will be registered using open-generics.

Adding declared registrations to the IServiceCollection collection

In your Program.cs, add a call to services.AddXxxServices(), where Xxx is the application identifier. By default, this is the short form of the assembly name. For example:

  • For a project named Web, it will be services.AddWebServices()
  • For a project named Application.Web, it will be services.AddApplicationWebServices()

However, this name can be overridden using [assembly: ImmediateAssemblyIdentifierAttribute("SomeIdentifier")].

Tags

Tags can be passed to selectively register only tagged services:

[RegisterSingleton(Tags=["tag-a"])]publicclassMyService;builder.Services.AddMyProjectServices("tag-a","tag-b");

Attribute Reference

All three lifetime attributes — RegisterSingleton, RegisterScoped, RegisterTransient — share the same properties.

ServiceType

Registers the class as the specified service type. The class must be assignable to it.

[RegisterSingleton(ServiceType=typeof(IMyService))]publicclassMyService:IMyService{}

Alternatively, a concrete registration may be declared using generic attributes.

[RegisterSingleton<IMyService>]publicclassMyService:IMyService{}[RegisterScoped<IService<string>>]publicclassMyService<T>:IMyService<string>

RegistrationStrategy

Controls which service types are generated. Mutually exclusive with ServiceType.

ValueEffect
None (default)Registers as ServiceType if provided, otherwise as the class itself
SelfRegisters as the concrete class
ImplementedInterfacesRegisters as each interface the class implements
SelfAndImplementedInterfacesRegisters as the concrete class and each interface
[RegisterSingleton(RegistrationStrategy=RegistrationStrategy.ImplementedInterfaces)]publicclassMyService:IMyService{}

DuplicateStrategy

Controls what happens when a registration for the same service type already exists.

ValueGenerated call
Append (default)services.Add(...)
Skipservices.TryAdd(...)
Replaceservices.Replace(...)

ServiceKey

Registers the service as a keyed service.

[RegisterSingleton(ServiceKey="my-key")]publicclassMyService{}

Factory

Name of a static factory method on the class to use as ImplementationFactory. The method must be static, return the class type, and accept (IServiceProvider) for non-keyed or (IServiceProvider, object) for keyed registrations. Cannot be combined with UseProxyFactory or used on open generic types. Factories cannot be used with generic target classes.

[RegisterSingleton(Factory=nameof(Create))]publicclassMyService{publicstaticMyServiceCreate(IServiceProvidersp)=>newMyService();}

UseProxyFactory

When true, the registration uses ServiceProviderServiceExtensions.GetRequiredService<T> (or the keyed equivalent) as the factory. This produces a proxy registration — it does not register the implementation itself, but resolves it from the container.

UseProxyFactory = true be combined with the following:

  • A provided Factory,
  • RegistrationStrategy = Self, or
  • Generic target classes
[RegisterSingleton(ServiceType=typeof(IMyService),UseProxyFactory=true)]publicclassMyService:IMyService{}

Tags

Assigns string tags to the registration. When AddXxxServices is called with tag arguments, only registrations that share at least one tag (or registrations with no tags) are included.

[RegisterSingleton(Tags=["worker","background"])]publicclassBackgroundWorker{}

Global Configuration

ServiceKey and DuplicationStrategy can be configured globally with [RegistrationDefaults] attribute applied to the assembly.

[assembly:RegistrationDefaults(RegistrationStrategy=RegistrationStrategy.SelfAndImplementedInterfaces,DuplicateStrategy=DuplicateStrategy.Replace,UseProxyFactory=true)]

Per-attribute values take precedence over assembly defaults.


[RegisterServices]

Apply this attribute to a static void method to have it called as part of AddXxxServices. The method must accept IServiceCollection as its first parameter, and optionally ReadOnlySpan<string> as its second parameter to receive the tags passed to AddXxxServices.

publicstaticclassManualRegistrations{[RegisterServices]publicstaticvoidRegister(IServiceCollectionservices){ ...}// or, to receive tags:[RegisterServices]publicstaticvoidRegisterWithTags(IServiceCollectionservices,ReadOnlySpan<string>tags){ ...}}

Migration

From Injectio

Note

Immediate.Injections uses a different default registration strategy than Injectio. For a clean migration, set [assembly: RegistrationDefaults(RegistrationStrategy = RegistrationStrategy.SelfAndImplementedInterfaces, UseProxyFactory = true)]

  • The Tags parameter receives a string[] instead of a comma-separated string. Example: Tags = "foo,bar" becomes Tags = ["foo", "bar"]
  • The RegistrationStrategy.SelfWithInterfaces enum value changes to RegistrationStrategy.SelfAndImplementedInterfaces
  • The Registration parameter changes to RegistrationStrategy
  • The Duplicate parameter becomes DuplicateStrategy
  • Assembly name override moves from MSBuild property to [ImmediateAssemblyIdentifier] attribute

From AutoRegisterInject

Note

Immediate.Injections uses a different default registration strategy than Injectio. For a clean migration, set [assembly: RegistrationDefaults(RegistrationStrategy = RegistrationStrategy.ImplementedInterfaces)].

  • The [TryRegisterXxx] attributes are removed; but the behavior is implemented using a parameter. Example: DuplicateStrategy = DuplicateStrategy.Skip

About

Source Generated MS.E.DependencyInjection registrations

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages