Do you know the best dependency injection container?

Last updated by Yazhi Chen [SSW] 20 days ago.See history

IoC (Inversion of Control) and Dependency Injection

IoC is a design pattern that shifts the responsibility of managing object dependencies from the individual classes to a centralized container or framework. This decoupling enhances flexibility and scalability by allowing the framework to handle object creation and wiring.

Dependency injection is a method for managing Inversion of Control (IoC). This involves creating an interface and passing it as a parameter, allowing us to determine which implementation of the interface we intend to use.

IoC containers

IoC containers are powerful tools that apply the IoC principle and automatically handle dependency resolution and object instantiation. They act as central repositories for services and take care of managing the lifespan of objects. At SSW we recommend using .NET built-in Dependency Injection as default. Read more on Dependency injection in ASP.NET Core.

However, in larger applications, manually registering dependencies can become cumbersome and easy to forget. In those cases, we recommend using Scrutor. While it isn't a DI container itself, it works on top of the .NET built-in Dependency Injection capabilities and adds assembly scanning to automatically register discovered types.

.NET IoC containers:

When selecting a Dependency Injection container it is worth considering a number of factors such as:

  • Ease of use
  • Configurability: Fluent API and/or XML Configuration
  • Performance (Unless you have a very high traffic application the difference should be minimal)
  • NuGet Support

The top tools all contain comparable functionality. In practice which one you use makes little difference, especially when you consider that your container choice should not leak into your domain model.

Important: Unless a specific shortfall is discovered with the container your team uses, you should continue to use the same container across all of your projects, become an expert with it and invest time on building features rather than learning new container implementations.

di container bad
Figure: Bad Example - Ninject and StructureMap were top containers but are no longer actively developed. Together with Autofac, they do not support the latest version of .NET

Examples of using IoC container

public class Program
{
    private static void Main()
    {        
        IContainer container = IoC.Initialize(); 
        new BadgeTaskJob(container).Run();
    }
}

Bad example - Use the StructureMap IoC container but did not do the proper dependency injection

var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddScoped<BadgeTaskJob>();
using IHost host = builder.Build();
using var scope = host.Services.CreateScope();
scope.ServiceProvider.GetRequiredService<BadgeTaskJob>().Run();

Good example - Use .NET built-in Dependency Injection for console app

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<ITelemetryInitializer, AppInsightsTelemetryInitializer>();
builder.Services.AddSingleton<AssetDomain>();
var app = builder.Build();
app.Run();

Good example - Use ASP.Net Core built-in Dependency Injection for web app

We open source. Powered by GitHub