DEV Community

Paul Welter for LoreSoft

Posted on • Originally published at loresoft.com on

Injectio - Source Generator for Dependency Injection

Source generator that helps register discovered services in the dependency injection container

Features

  • Transient, Singleton, Scoped service registration
  • Factory registration
  • Module method registration
  • Duplicate Strategy - Skip,Replace,Append
  • Registration Strategy - Self, Implemented Interfaces, Self With Interfaces

Usage

Add package

Add the nuget package project to your projects.

dotnet add package Injectio

Prevent dependances from including Injectio

<PackageReference Include="Injectio" PrivateAssets="all" />
Enter fullscreen mode Exit fullscreen mode

Registration Attributes

Place registration attribute on class. The class will be discovered and registered.

  • [RegisterSingleton] Marks the class as a singleton service
  • [RegisterScoped] Marks the class as a scoped service
  • [RegisterTransient] Marks the class as a transient service
  • [RegisterServices] Marks the method to be called to register services

Attribute Properties

Property Description
ImplementationType The type that implements the service. If not set, the class the interface is on will be used.
ServiceType The type of the service. If not set, the Registration property used to determine what is registered.
Factory Name of a factory method to create new instances of the service implementation.
Duplicate How the generator handles duplicate registrations. See Duplicate Strategy
Registration How the generator determines what to register. See Registration Strategy

Duplicate Strategy

Value Description
Skip Skips registrations for services that already exists
Replace Replaces existing service registrations
Append Appends a new registration for existing services

Registration Strategy

Value Description
Self Registers each matching concrete type as itself
ImplementedInterfaces Registers each matching concrete type as all of its implemented interfaces
SelfWithInterfaces Registers each matching concrete type as all of its implemented interfaces and itself

Singleton services

[RegisterSingleton]
public class SingletonService : IService { }
Enter fullscreen mode Exit fullscreen mode

Explicit service type

[RegisterSingleton(ServiceType = typeof(IService))]
public class SingletonService : IService { }
Enter fullscreen mode Exit fullscreen mode

Scoped Services

[RegisterScoped]
public class ScopedService : IService { }
Enter fullscreen mode Exit fullscreen mode

Transient Services

[RegisterTransient]
public class TransientService : IService { }
Enter fullscreen mode Exit fullscreen mode

Factories

[RegisterTransient(Factory = nameof(ServiceFactory))]
public class FactoryService : IFactoryService
{
    private readonly IService _service;

    public FactoryService(IService service)
    { 
        _service = service;
    }

    public static IFactoryService ServiceFactory(IServiceProvider serviceProvider)
    {
        return new FactoryService(serviceProvider.GetService<IService>());
    }
}
Enter fullscreen mode Exit fullscreen mode

Open Generic

[RegisterSingleton(ImplementationType = typeof(OpenGeneric<>), ServiceType = typeof(IOpenGeneric<>))]
public class OpenGeneric<T> : IOpenGeneric<T> { }
Enter fullscreen mode Exit fullscreen mode

Register Method

When the service registration is complex, use the RegisterServices attribute on a method that has a parameter of IServiceCollection or ServiceCollection

public class RegistrationModule
{
    [RegisterServices]
    public static void Register(IServiceCollection services)
    {
        services.TryAddTransient<IModuleService, ModuleService>();
    }
}
Enter fullscreen mode Exit fullscreen mode

Add to container

The source generator creates an extension method with all the discovered services registered. Call the generated extension method to add the services to the container. The method will be called Add[AssemblyName]. The assembly name will have the dots removed.

var services = new ServiceCollection();
services.AddInjectioTestsConsole();
Enter fullscreen mode Exit fullscreen mode

Override the extension method name by using the InjectioName MSBuild property.

<PropertyGroup>
  <InjectioName>Library</InjectioName>
</PropertyGroup>
Enter fullscreen mode Exit fullscreen mode
var services = new ServiceCollection();
services.AddLibrary();
Enter fullscreen mode Exit fullscreen mode

Top comments (0)