AutoRegisterInject by Patrick Klaeren
Nuget / site data
Details
Info
Name: AutoRegisterInject
C# Source Generator to automatically register dependencies in Microsoft Dependency Injection Service Collection
Author: Patrick Klaeren
NuGet: https://www.nuget.org/packages/AutoRegisterInject/
You can find more details at https://github.com/patrickklaeren/AutoRegisterInject
Source : https://github.com/patrickklaeren/AutoRegisterInject
Original Readme
AutoRegisterInject
AutoRegisterInject, also referred to as ARI, is a C# source generator that will automatically create Microsoft.Extensions.DependencyInjection registrations for types marked with attributes.
This is a compile time alternative to reflection/assembly scanning for your injections or manually adding to the ServiceCollection
every time a new type needs to be registered.
For example:
namespace MyProject;
[RegisterScoped]
public class Foo { }
will automatically generate an extension method called AutoRegister()
for IServiceProvider
, that registers Foo
, as scoped.
internal IServiceCollection AutoRegister(this IServiceCollection serviceCollection)
{
serviceCollection.AddScoped<Foo>();
return serviceCollection;
}
In larger projects, dependency injection registration becomes tedious and in team situations can lead to merge conflicts which can be easily avoided.
AutoRegisterInject moves the responsibility of service registration to the owning type rather than external service collection configuration, giving control and oversight of the type that is going to be registered with the container.
Installation
Install the Nuget package, and start decorating classes with ARI attributes.
Use dotnet add package AutoRegisterInject
or add a package reference manually:
<PackageReference Include="AutoRegisterInject" />
Usage
Classes should be decorated with one of four attributes:
[RegisterScoped]
[RegisterSingleton]
[RegisterTransient]
[RegisterHostedService]
Register a class:
[RegisterScoped]
class Foo;
and get the following output:
serviceCollection.AddScoped<Foo>();
Update the service collection by invoking:
var serviceCollection = new ServiceCollection();
serviceCollection.AutoRegister();
serviceCollection.BuildServiceProvider();
You can now inject Foo
as a dependency and have this resolved as scoped.
Alternatively, you can register hosted services by:
[RegisterHostedService]
class Foo;
and get:
serviceCollection.AddHostedService<Foo>();
Register as interface
Implement one or many interfaces on your target class:
[RegisterTransient]
class Bar : IBar;
and get the following output:
serviceCollection.AddTransient<IBar, Bar>();
Important note: AutoRegisterInject is opinionated and Bar
will only be registered with its implemented interface. ARI will not register Bar
. Bar
will always need to be resolved from IBar
in your code.
Implementing multiple interfaces will have the implementing type be registered for each distinct interface.
[RegisterTransient]
class Bar : IBar, IFoo, IBaz;
will output the following:
serviceCollection.AddTransient<IBar, Bar>();
serviceCollection.AddTransient<IFoo, Bar>();
serviceCollection.AddTransient<IBaz, Bar>();
Important note: AutoRegisterInject is opinionated and Bar
will only be registered with its implemented interfaces. ARI will not register Bar
. Bar
will always need to be resolved from IBar
, IFoo
or IBaz
in your code.
Multiple assemblies
In addition to the AutoRegister
extension method, every assembly that AutoRegisterInject is a part of, a AutoRegisterFromAssemblyName
will be generated. This allows you to configure your service collection from one, main, executing assembly.
Given 3 assemblies, MyProject.Main
, MyProject.Services
, MyProject.Data
, you can configure the ServiceCollection
as such:
var serviceCollection = new ServiceCollection();
serviceCollection.AutoRegisterFromMyProjectMain();
serviceCollection.AutoRegisterFromMyProjectServices();
serviceCollection.AutoRegisterFromMyProjectData();
serviceCollection.BuildServiceProvider();
AutoRegisterInject will remove illegal characters from assembly names in order to generate legal C# method names. ,
, .
and
will be removed.
License
AutoRegisterInject is MIT licensed. Do with it what you please under the terms of MIT.
About
Generating class DI registration from attributes
How to use
Example ( source csproj, source files )
- CSharp Project
- Program.cs
- Database.cs
- IDatabase.cs
- DatabaseCon.cs
This is the CSharp Project that references AutoRegisterInject
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoRegisterInject" Version="1.2.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
This is the use of AutoRegisterInject in Program.cs
// See https://aka.ms/new-console-template for more information
using AutoRegisterInjectDemo;
using Microsoft.Extensions.DependencyInjection;
Console.WriteLine("Hello, World!");
ServiceCollection sc = new();
sc.AutoRegisterFromAutoRegisterInjectDemo();
var b=sc.BuildServiceProvider();
var con = b.GetRequiredService<DatabaseCon>();
var db=b.GetRequiredService<IDatabase>();
db.Open();
This is the use of AutoRegisterInject in Database.cs
namespace AutoRegisterInjectDemo;
[RegisterScoped]
internal class Database : IDatabase
{
private readonly DatabaseCon con;
public Database(DatabaseCon con)
{
this.con = con;
}
public void Open()
{
Console.WriteLine($"open {con.Connection}");
}
}
This is the use of AutoRegisterInject in IDatabase.cs
namespace AutoRegisterInjectDemo
{
internal interface IDatabase
{
void Open();
}
}
This is the use of AutoRegisterInject in DatabaseCon.cs
namespace AutoRegisterInjectDemo;
[RegisterSingleton]
internal class DatabaseCon
{
public string? Connection { get; set; }
}
Generated Files
Those are taken from $(BaseIntermediateOutputPath)\GX
- AutoRegisterInject.Attributes.g.cs
- AutoRegisterInject.ServiceCollectionExtension.g.cs
// <auto-generated>
// Automatically generated by AutoRegisterInject.
// Changes made to this file may be lost and may cause undesirable behaviour.
// </auto-generated>
[System.AttributeUsage(System.AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
internal sealed class RegisterScopedAttribute : System.Attribute { }
[System.AttributeUsage(System.AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
internal sealed class RegisterSingletonAttribute : System.Attribute { }
[System.AttributeUsage(System.AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
internal sealed class RegisterTransientAttribute : System.Attribute { }
[System.AttributeUsage(System.AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
internal sealed class RegisterHostedServiceAttribute : System.Attribute { }
// <auto-generated>
// Automatically generated by AutoRegisterInject.
// Changes made to this file may be lost and may cause undesirable behaviour.
// </auto-generated>
using Microsoft.Extensions.DependencyInjection;
public static class AutoRegisterInjectServiceCollectionExtension
{
public static Microsoft.Extensions.DependencyInjection.IServiceCollection AutoRegisterFromAutoRegisterInjectDemo(this Microsoft.Extensions.DependencyInjection.IServiceCollection serviceCollection)
{
return AutoRegister(serviceCollection);
}
internal static Microsoft.Extensions.DependencyInjection.IServiceCollection AutoRegister(this Microsoft.Extensions.DependencyInjection.IServiceCollection serviceCollection)
{
serviceCollection.AddScoped<AutoRegisterInjectDemo.IDatabase, AutoRegisterInjectDemo.Database>();
serviceCollection.AddSingleton<AutoRegisterInjectDemo.DatabaseCon>();
return serviceCollection;
}
}
Usefull
Download Example (.NET C# )
Share AutoRegisterInject
https://ignatandrei.github.io/RSCG_Examples/v2/docs/AutoRegisterInject