JZen.AutoInject 1.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package JZen.AutoInject --version 1.1.0
                    
NuGet\Install-Package JZen.AutoInject -Version 1.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="JZen.AutoInject" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="JZen.AutoInject" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="JZen.AutoInject" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add JZen.AutoInject --version 1.1.0
                    
#r "nuget: JZen.AutoInject, 1.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package JZen.AutoInject@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=JZen.AutoInject&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=JZen.AutoInject&version=1.1.0
                    
Install as a Cake Tool

πŸš€ AutoInject

.NET 8.0 License: MIT NuGet

Stop writing constructor injection boilerplate! πŸ›‘
AutoInject is a lightweight library that brings attribute-based dependency injection to .NET, eliminating the need for constructor injection hell.

🎯 Why AutoInject?

Tired of this? 😀

public class OrderService
{
    private readonly IRepository _repository;
    private readonly IEmailService _emailService;
    private readonly ILogger<OrderService> _logger;
    private readonly IPaymentService _paymentService;
    private readonly INotificationService _notificationService;

    public OrderService(
        IRepository repository,
        IEmailService emailService,
        ILogger<OrderService> logger,
        IPaymentService paymentService,
        INotificationService notificationService)
    {
        _repository = repository;
        _emailService = emailService;
        _logger = logger;
        _paymentService = paymentService;
        _notificationService = notificationService;
    }
}

With AutoInject, write this instead: ✨

[AutoInject]
public class OrderService
{
    [Injectable] private readonly IRepository _repository;
    [Injectable] private readonly IEmailService _emailService;
    [Injectable] private readonly ILogger<OrderService> _logger;
    [Injectable] private readonly IPaymentService _paymentService;
    [Injectable] private readonly INotificationService _notificationService;

    // Clean constructor - no dependencies!
    public OrderService() { }
}

🌟 Key Features

  • βœ… Zero Boilerplate: No more constructor injection bloat
  • βœ… Attribute-Based: Simple [AutoInject] and [Injectable] attributes
  • βœ… ASP.NET Core Integration: Seamless integration with built-in DI container
  • βœ… Automatic Registration: Auto-scan and register your classes
  • βœ… Scoped Management: Automatic scope management for web requests
  • βœ… Logger Support: Built-in logger injection support
  • βœ… Performance Optimized: Type caching for reflection operations
  • βœ… Thread-Safe: Safe for concurrent operations

πŸ“¦ Installation

# Install from NuGet
Install-Package JZen.AutoInject

Or via .NET CLI:

dotnet add package JZen.AutoInject

Or add to your .csproj:

<PackageReference Include="JZen.AutoInject" Version="1.1.0" />

πŸš€ Quick Start

1. Configure your services in Program.cs

using AutoInject.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Register your services
builder.Services.AddScoped<IRepository, Repository>();
builder.Services.AddScoped<IEmailService, EmailService>();

// πŸ”₯ Auto-register all classes marked with [AutoInject]
builder.Services.AddAutoInjectClasses(Assembly.GetExecutingAssembly());

var app = builder.Build();

// πŸ”₯ Enable AutoInject
app.UseFactoryDependencyInjection();

app.Run();

2. Mark your classes with [AutoInject]

using AutoInject.Attributes;

[AutoInject]
public class OrderService
{
    [Injectable] private readonly IRepository _repository;
    [Injectable] private readonly IEmailService _emailService;
    [Injectable] private readonly ILogger<OrderService> _logger;

    public async Task ProcessOrderAsync(Order order)
    {
        _logger.LogInformation("Processing order {OrderId}", order.Id);
        
        await _repository.SaveAsync(order);
        await _emailService.SendConfirmationAsync(order.CustomerEmail);
        
        _logger.LogInformation("Order {OrderId} processed successfully", order.Id);
    }
}

3. Use your services normally

[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
    private readonly OrderService _orderService;

    public OrdersController(OrderService orderService)
    {
        _orderService = orderService;
    }

    [HttpPost]
    public async Task<IActionResult> CreateOrder([FromBody] Order order)
    {
        await _orderService.ProcessOrderAsync(order);
        return Ok();
    }
}

πŸ†• NEW: InjectBase Auto-Registration

Version 1.1.0 introduces AddInjectBaseClasses() - automatic registration for classes that inherit from InjectBase!

🎯 The Problem

You have repository classes that inherit from InjectBase with [Injectable] properties, but you still need to manually register their dependencies:

// Manual registration (tedious!)
services.AddScoped<IUsuarioLogado, UsuarioLogadoService>();
services.AddScoped<IEmailService, EmailService>();
services.AddScoped<UsuarioRepository>();
services.AddScoped<ProdutoRepository>();
// ... and so on for each dependency

✨ The Solution

// One line registers everything automatically!
services.AddInjectBaseClasses();

πŸš€ How to Use

1. Create your InjectBase classes:
public class UsuarioRepository : InjectBase
{
    [Injectable]
    protected readonly IUsuarioLogado _usuarioLogado;

    [Injectable]
    protected readonly IEmailService _emailService;

    public string GetCurrentUserData()
    {
        return $"User: {_usuarioLogado.GetUsuarioNome()}";
    }
}

// Implementations
public class UsuarioLogadoService : IUsuarioLogado
{
    public string GetUsuarioNome() => "JoΓ£o Silva";
}

public class EmailService : IEmailService
{
    public Task SendEmailAsync(string email) => Task.CompletedTask;
}
2. Register everything automatically:
var builder = WebApplication.CreateBuilder(args);

// πŸ”₯ This single line:
// βœ… Finds all classes that inherit from InjectBase
// βœ… Discovers their [Injectable] properties  
// βœ… Finds implementations for each interface
// βœ… Registers everything in DI container
builder.Services.AddInjectBaseClasses();

var app = builder.Build();
3. Use your repositories normally:
[ApiController]
public class UsuarioController : ControllerBase
{
    private readonly UsuarioRepository _repository;

    public UsuarioController(UsuarioRepository repository)
    {
        _repository = repository; // Fully injected and ready!
    }
}

πŸŽ›οΈ Advanced Options

// Specific assembly
services.AddInjectBaseClasses(typeof(MyRepository).Assembly);

// Multiple assemblies
services.AddInjectBaseClasses(new[] { assembly1, assembly2 });

// Different lifetime
services.AddInjectBaseClasses(ServiceLifetime.Singleton);

🀝 Combine Both Approaches

services.AddAutoInjectClasses();    // For [AutoInject] classes
services.AddInjectBaseClasses();    // For InjectBase classes

πŸ“š Advanced Usage

Inherit from InjectBase (Alternative Approach)

using AutoInject;

public class OrderService : InjectBase
{
    [Injectable] private readonly IRepository _repository;
    [Injectable] private readonly IEmailService _emailService;
    
    // Logger is automatically available as _logger
    public void ProcessOrder()
    {
        _logger.LogInformation("Processing order...");
        // Your logic here
    }
}

Automatic Interface Registration

// Register all interfaces from a specific namespace
builder.Services.AddScopedInjection("MyApp.Application.UseCases");

Multiple Assembly Registration

var assemblies = new[] 
{ 
    Assembly.GetExecutingAssembly(),
    typeof(SomeOtherClass).Assembly 
};

builder.Services.AddAutoInjectClasses(assemblies);

Custom Service Lifetimes

// Register as Singleton
builder.Services.AddAutoInjectClasses(
    Assembly.GetExecutingAssembly(), 
    ServiceLifetime.Singleton
);

πŸ”§ How It Works

AutoInject uses a combination of:

  1. Reflection: To discover types and properties marked with attributes
  2. Custom Factory: Creates instances and injects dependencies
  3. Interceptors: Automatically process classes during instantiation
  4. Middleware: Manages scoped services lifecycle in web applications
  5. Caching: Optimizes reflection operations for better performance

Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   [AutoInject]  │───▢│     Factory     │───▢│  DI Container   β”‚
β”‚     Classes     β”‚    β”‚   + Interceptor β”‚    β”‚   (ASP.NET)     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                        β”‚                        β”‚
         β–Ό                        β–Ό                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   [Injectable]  β”‚    β”‚   Auto-Factory  β”‚    β”‚   Scope Mgmt    β”‚
β”‚   Properties    β”‚    β”‚   Registration  β”‚    β”‚   Middleware    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎯 Best Practices

βœ… DO

[AutoInject]
public class UserService
{
    [Injectable] private readonly IUserRepository _userRepository;
    [Injectable] private readonly ILogger<UserService> _logger;
    
    // Use private readonly fields
    // Mark with [Injectable]
    // Keep constructors clean
}

❌ DON'T

[AutoInject]
public class UserService
{
    [Injectable] public IUserRepository UserRepository; // Don't use public fields
    [Injectable] private ILogger<UserService> _logger;  // Don't use mutable fields
    
    // Don't mix constructor injection with AutoInject
    public UserService(ISomeService service) { }
}

πŸ” Comparison

Feature Constructor Injection AutoInject
Boilerplate Code High πŸ“ˆ Minimal ✨
Readability Cluttered 😡 Clean 🧹
Refactoring Painful 😀 Easy 🎯
Performance Faster πŸƒβ€β™‚οΈ Slightly Slower πŸšΆβ€β™‚οΈ
Learning Curve Standard πŸ“š Minimal πŸŽ“

🀝 Contributing

We welcome contributions! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™‹β€β™‚οΈ Support


Made with ❀️ by developers who hate constructor injection boilerplate!

"Life's too short for constructor injection hell" - Anonymous Developer

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.1 152 6/3/2025
2.0.0 143 6/3/2025
1.1.0 144 6/3/2025
1.0.0 150 5/29/2025

v1.1.0: Added AddInjectBaseClasses() method for automatic registration of classes that inherit from InjectBase and their [Injectable] dependencies. This eliminates the need to manually register dependencies for repository and service classes that use the InjectBase pattern.