Simplifying Dependency Injection with Campsis.AutoInject

Mabrouk Mahdhi
2 min readJan 30, 2025
Photo by Diana Polekhina on Unsplash

Dependency Injection (DI) is a cornerstone of modern .NET applications, ensuring loose coupling, testability, and maintainability. However, traditional DI configurations can quickly become verbose and boilerplate-heavy. Developers often find themselves manually registering every service, leading to cluttered Program.cs files and a tedious onboarding experience.

Enter Campsis.AutoInject — a lightweight yet powerful automatic DI registration library that eliminates boilerplate code, making .NET DI effortless and intuitive. This article explores the why, how, and real-world benefits of using Campsis.AutoInject in your next project.

The Problem with Manual DI

Imagine a standard .NET application with multiple services:

services.AddScoped<IUserService, UserService>();
services.AddSingleton<ICacheService, MemoryCacheService>();
services.AddTransient<ILogger, Logger>();

For every new service, you must:

  1. Remember to register it in Program.cs.
  2. Choose the correct lifecycle (Scoped, Singleton, Transient).
  3. Handle service variations (e.g., multiple implementations).

This process is not only redundant but also error-prone — if you forget to register a service, runtime errors will follow.

The Campsis.AutoInject Solution

Campsis.AutoInject automates service registration by scanning assemblies for annotated classes and registering them accordingly.

How It Works

Simply annotate your services with SingletonAttribute, ScopedAttribute, or TransientAttribute:

[Singleton(typeof(IUserService))]
public class UserService : IUserService { }

[Scoped(typeof(ICacheService))]
public class MemoryCacheService : ICacheService { }

[Transient(typeof(ILogger))]
public class Logger : ILogger { }

Then, in Program.cs, just call one method:

builder.Services.UseAutoInjection();

That’s it! Campsis.AutoInject scans your assembly, finds the annotated services, and registers them automatically.

Keyed Injection

Campsis.AutoInject supports keyed dependencies, allowing multiple implementations of the same interface.

Example: Injecting Multiple Storage Implementations

[Singleton(typeof(IStorageBroker), WithKey : "SQL")]
public class SqlStorageBroker : IStorageBroker { }

[Singleton(typeof(IStorageBroker), WithKey : "MONGO")]
public class MongoStorageBroker : IStorageBroker { }

Then inject the appropriate implementation using FromKeyedServices:

[Singleton(typeof(IStudentService))]
public class StudentService(
[FromKeyedServices("SQL"
)] IStorageBroker sqlStorageBroker,
[FromKeyedServices("MONGO")] IStorageBroker mongoStorageBroker) : IStudentService

{
public ValueTask<string> InsertStudentIntoMongoAsync(string student) =>
mongoStorageBroker.InsertStudentAsync(student);

public ValueTask<string> InsertStudentIntoSQLAsync(string student) =>
sqlStorageBroker.InsertStudentAsync(student);
}

This allows seamless switching between different implementations at runtime.

Why Choose Campsis.AutoInject?

  • Eliminates repetitive DI code
  • Prevents forgotten registrations
  • Encourages clean architecture
  • Works seamlessly in Blazor, ASP.NET Core, and console apps.

Try it today

Install the library and try it! waiting your feedback :)

dotnet add package Campsis.AutoInject

Happy coding!

Mabrouk Mahdhi
Mabrouk Mahdhi

Written by Mabrouk Mahdhi

Founder @ CodeCampsis, Microsoft MVP

No responses yet

Write a response