Tolitech.DependencyInjection.Extensions is a lightweight and modern .NET library that simplifies the discovery and automatic registration of interfaces and implementations (services, repositories, etc.) in the Dependency Injection (DI) container. It eliminates the manual work of mapping each interface to its implementation, making DI setup cleaner, more productive, and safer.
- Automatic registration of services, repositories, and dependencies via assembly scanning.
- Support for Transient, Scoped, and Singleton lifetimes.
- Native integration with
Microsoft.Extensions.DependencyInjection. - Focus on performance and simplicity.
Via NuGet Package Manager:
Install-Package Tolitech.DependencyInjection.Extensions
Or via .NET CLI:
dotnet add package Tolitech.DependencyInjection.Extensions
The library exposes extension methods for IServiceCollection that scan an assembly and automatically register all interface implementations inherited from a base type (e.g., IService, IRepository).
ScanAndAddTransient<TBase>(Assembly assembly)ScanAndAddScoped<TBase>(Assembly assembly)ScanAndAddSingleton<TBase>(Assembly assembly)
Each method registers all implementations of interfaces that inherit from TBase found in the specified assembly.
Suppose you have the following interfaces and implementations:
// Base interface
internal interface IService { }
// Specific interface
internal interface ICategoryService : IService
{
bool IsOK();
}
// Implementation
internal sealed class CategoryService : ICategoryService
{
public bool IsOK() => true;
}To automatically register all services implementing IService:
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
using Tolitech.DependencyInjection.Extensions;
var services = new ServiceCollection();
Assembly assembly = Assembly.GetExecutingAssembly();
// Register all services implementing IService as Scoped
services.ScanAndAddScoped<IService>(assembly);
// Resolve via DI
var provider = services.BuildServiceProvider();
var categoryService = provider.GetService<ICategoryService>();The same applies to repositories or any other base interface pattern.
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
using Tolitech.DependencyInjection.Extensions;
var services = new ServiceCollection();
Assembly assembly = Assembly.GetExecutingAssembly();
// Transient
services.ScanAndAddTransient<IRepository>(assembly);
// Scoped
services.ScanAndAddScoped<IService>(assembly);
// Singleton
services.ScanAndAddSingleton<IService>(assembly);The library uses reflection to:
- Find all concrete classes in the specified assembly.
- Identify all implemented interfaces that inherit from the specified base type.
- Register each found interface with its corresponding implementation in the desired lifetime.
Example method signature:
public static IServiceCollection ScanAndAddScoped<T>(this IServiceCollection services, Assembly assembly)The library includes unit tests using xUnit, ensuring the correct operation of automatic registration methods for all lifetimes (Transient, Scoped, Singleton).
Test example:
[Fact]
public void AddScoped_AddServiceCorrectly()
{
var builder = new HostApplicationBuilder();
Assembly assembly = Assembly.GetExecutingAssembly();
builder.Services.ScanAndAddScoped<IService>(assembly);
var provider = builder.Services.BuildServiceProvider();
var categoryService = provider.GetService<ICategoryService>();
Assert.NotNull(categoryService);
Assert.True(categoryService.IsOK());
}- Projects with many services/repositories and interface conventions.
- APIs, web applications, microservices, and modular systems.
- Situations where productivity and DI standardization are essential.
- Reduces repetitive code and manual registration errors.
- Facilitates project maintenance and evolution.
- Follows .NET Dependency Injection best practices.