EasyServiceRegister 3.0.2

dotnet add package EasyServiceRegister --version 3.0.2
                    
NuGet\Install-Package EasyServiceRegister -Version 3.0.2
                    
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="EasyServiceRegister" Version="3.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EasyServiceRegister" Version="3.0.2" />
                    
Directory.Packages.props
<PackageReference Include="EasyServiceRegister" />
                    
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 EasyServiceRegister --version 3.0.2
                    
#r "nuget: EasyServiceRegister, 3.0.2"
                    
#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.
#addin nuget:?package=EasyServiceRegister&version=3.0.2
                    
Install as a Cake Addin
#tool nuget:?package=EasyServiceRegister&version=3.0.2
                    
Install as a Cake Tool

EasyServiceRegister

Simple, Attribute-Based Dependency Injection for .NET

EasyServiceRegister is a lightweight library built on top of Microsoft.Extensions.DependencyInjection.Abstractions. It simplifies the registration of services using attributes, supporting lifetimes, keyed services, decorators, and validation โ€” all with minimal boilerplate.

โœ… Now supporting keyed services (.NET 8+) and registration diagnostics in v3.0.0+


๐Ÿš€ Installation

Install via NuGet:

dotnet add package EasyServiceRegister

โš™๏ธ How It Works

1. Add a registration attribute to your service class:

Attribute Description
[RegisterAsSingleton] Registers as a singleton
[RegisterAsScoped] Registers as scoped
[RegisterAsTransient] Registers as transient
[RegisterAsSingletonKeyed("key")] Singleton with a key (requires .NET 8+)
[RegisterAsScopedKeyed("key")] Scoped with a key
[RegisterAsTransientKeyed("key")] Transient with a key

Optional parameters like useTryAddSingleton, useTryAddScoped, or useTryAddTransient let you control whether to use TryAdd or Add.

If your service implements multiple interfaces, you can specify the intended one using serviceInterface:

[RegisterAsScoped(serviceInterface: typeof(ISomeService))]
public class SomeService : ISomeService, IDisposable
{
    // ...
}

2. Register All Services

Call AddServices in your Startup.cs or Program.cs:

services.AddServices(typeof(MyServiceMarkerType)); // Marker class from your assembly

// or

services.AddServices(typeof(Assembly1), typeof(Assembly2));

๐Ÿ“ฆ Examples

Simple Scoped Service

[RegisterAsScoped]
public class ProductService : IProductService
{
    public Task<Product> CreateProduct(Product product)
    {
        // Implementation
    }
}

Singleton with TryAdd

[RegisterAsSingleton(useTryAddSingleton: true)]
public class CurrentUserProvider
{
    public Task<User> GetCurrentUser()
    {
        // Implementation
    }
}

๐Ÿ”‘ Keyed Services (.NET 8+)

Register and resolve services by key:

[RegisterAsSingletonKeyed("primary")]
public class PrimaryEmailService : IEmailService { }

[RegisterAsSingletonKeyed("secondary")]
public class SecondaryEmailService : IEmailService { }
public class EmailManager
{
    public EmailManager(
        [FromKeyedServices("primary")] IEmailService primary,
        [FromKeyedServices("secondary")] IEmailService secondary)
    {
        // Use services
    }
}

๐Ÿงฑ Decorator Pattern Support

Easily layer cross-cutting concerns:

public interface INotificationService
{
    MessageDto Send(string message);
}

[RegisterAsScoped]
[DecorateWith(typeof(LoggingDecorator), order: 0)]
[DecorateWith(typeof(StoreNotificationDecorator), order: 1)]
public class EmailNotificationService : INotificationService
{
    public MessageDto Send(string message)
    {
        // Send email notification
    }
}

public class LoggingDecorator : INotificationService
{
    private readonly INotificationService _inner;
    private readonly ILogger _logger;

    public LoggingDecorator(INotificationService inner, ILogger logger)
    {
        _inner = inner;
        _logger = logger;
    }

    public MessageDto Send(string message)
    {
        _logger.LogInformation("Sending: {message}", message);
        _inner.Send(message);
        _logger.LogInformation("Sent: {message}", message);
    }
}

public class StoreNotificationDecorator : INotificationService
{
    private readonly INotificationService _inner;
    private readonly DbContext _dbContext;

    public StoreNotificationDecorator(INotificationService inner, DbContext dbContext)
    {
        _inner = inner;
        _dbContext = dbContext;
    }

    public void Send(string message)
    {
       var messageDto = _inner.Send(message);
       _dbContext.Messages.Add(messageDto);
       _dbContext.SaveChanges();
    }
}

๐Ÿงช Diagnostics & Validation

๐Ÿ” List Registered Services

var registered = ServicesExtension.GetRegisteredServices();

foreach (var svc in registered)
{
    Console.WriteLine($"Type: {svc.ServiceType}, Impl: {svc.ImplementationType}, Lifetime: {svc.Lifetime}, Key: {svc.ServiceKey}");
}

โš ๏ธ Detect Anti-Patterns

Find issues like circular dependencies or incorrect lifetimes:

var issues = builder.Services.ValidateServices();

foreach (var issue in issues)
{
    Console.WriteLine(issue.Message);
}

โœ… Why Use EasyServiceRegister?

  • โœ… Eliminates repetitive service registration
  • โœ… Works with standard IServiceCollection
  • โœ… Supports decorators, keyed services, and diagnostics
  • โœ… Keeps your startup file clean and maintainable

๐Ÿ“„ License

MIT ยฉ

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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
3.0.2 58 7/5/2025
3.0.1 82 7/4/2025
3.0.0 89 7/4/2025
2.2.1 228 6/1/2025
2.2.0 140 6/1/2025
2.1.0 387 5/1/2025
2.0.9 7,285 12/6/2023
2.0.8 170 12/5/2023
2.0.7 129 12/5/2023
2.0.6 803 4/29/2023
2.0.5 2,676 11/26/2022
2.0.4 353 11/23/2022
2.0.3 382 11/20/2022
2.0.2 357 11/19/2022
2.0.1 337 11/19/2022
2.0.0 350 11/19/2022
1.0.2 2,960 5/8/2022
1.0.1 479 5/8/2022
1.0.0 625 1/19/2022
0.0.9 441 1/20/2022
0.0.8 469 1/20/2022