Skip to main content

Injectio by LoreSoft

Nuget / site data

Nuget GitHub last commit GitHub Repo stars

Details

Info

info

Name: Injectio

Source generator that automatically registers discovered services in dependency injection

Author: LoreSoft

NuGet: https://www.nuget.org/packages/Injectio/

You can find more details at https://github.com/loresoft/Injectio

Source : https://github.com/loresoft/Injectio

Original Readme

note

Injectio

Source generator that helps register attribute marked services in the dependency injection ServiceCollection

Source generator

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" />

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

PropertyDescription
ImplementationTypeThe type that implements the service. If not set, the class the attribute is on will be used.
ServiceTypeThe type of the service. If not set, the Registration property used to determine what is registered.
FactoryName of a factory method to create new instances of the service implementation.
DuplicateHow the generator handles duplicate registrations. See Duplicate Strategy
RegistrationHow the generator determines what to register. See Registration Strategy

Duplicate Strategy

ValueDescription
SkipSkips registrations for services that already exists
ReplaceReplaces existing service registrations
AppendAppends a new registration for existing services

Registration Strategy

ValueDescription
SelfRegisters each matching concrete type as itself
ImplementedInterfacesRegisters each matching concrete type as all of its implemented interfaces
SelfWithInterfacesRegisters each matching concrete type as all of its implemented interfaces and itself

Singleton services

[RegisterSingleton]
public class SingletonService : IService { }

Explicit service type

[RegisterSingleton(ServiceType = typeof(IService))]
public class SingletonService : IService { }

Support resolving multiple services with IEnumerable<T>

[RegisterSingleton(Duplicate = DuplicateStrategy.Append)]
public class SingletonService : IService { }

Scoped Services

[RegisterScoped]
public class ScopedService : IService { }

Transient Services

[RegisterTransient]
public class TransientService : IService { }

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>());
}
}

Generic Attributes

You can use generic attributes to register services if your project targets net7.0.

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0</TargetFrameworks>
</PropertyGroup>
</Project>

Generic attributes allow declaration to be more compact by avoiding the typeof calls

[RegisterSingleton<IService>]
public class ServiceImplementation : IService { }

Open Generic

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

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>();
}
}

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 extension method will be called Add[AssemblyName]. The assembly name will have the dots removed.

var services = new ServiceCollection();
services.AddInjectioTestsConsole();

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

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

Registration Tags

Control what is registered when calling the generated extension method using Tags

Tag the service

public interface IServiceTag
{
}

[RegisterSingleton(Tags = "Client,FrontEnd")]
public class ServiceTag : IServiceTag
{
}

Specify tags when adding to service collection. Note, if no tags specified, all services are registered

var services = new ServiceCollection();
services.AddInjectioTestsLibrary("Client");

About

note

Attributes to DI helper

How to use

Example ( source csproj, source files )

This is the CSharp Project that references Injectio

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Injectio" Version="2.6.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>

Generated Files

Those are taken from $(BaseIntermediateOutputPath)\GX

// <auto-generated />
#nullable enable

namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Extension methods for discovered service registrations
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCode("Injectio.Generators", "2.6.1.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.Diagnostics.DebuggerStepThroughAttribute]
public static class DiscoveredServicesExtensions
{
/// <summary>
/// Adds discovered services from InjectioDemo to the specified service collection
/// </summary>
/// <param name="serviceCollection">The service collection.</param>
/// <param name="tags">The service registration tags to include.</param>
/// <returns>The service collection</returns>
public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddInjectioDemo(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection serviceCollection, params string[]? tags)
{
var tagSet = new global::System.Collections.Generic.HashSet<string>(tags ?? global::System.Linq.Enumerable.Empty<string>());

global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAdd(
serviceCollection,
global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor.Describe(
typeof(global::InjectioDemo.IDatabase),
typeof(global::InjectioDemo.Database),
global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Scoped
)
);

global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAdd(
serviceCollection,
global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor.Describe(
typeof(global::InjectioDemo.Database),
typeof(global::InjectioDemo.Database),
global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Scoped
)
);

global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAdd(
serviceCollection,
global::Microsoft.Extensions.DependencyInjection.ServiceDescriptor.Describe(
typeof(global::InjectioDemo.DatabaseCon),
typeof(global::InjectioDemo.DatabaseCon),
global::Microsoft.Extensions.DependencyInjection.ServiceLifetime.Singleton
)
);

return serviceCollection;
}
}
}

Usefull

Download Example (.NET C# )

Share Injectio

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Injectio

In the same category (DependencyInjection) - 2 other generators

AutoRegisterInject

jab