Technology Sharing

C# IOC container, dependency injection and inversion of control

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Inversion of Control (IoC)

definition:Inversion of Control is a design principle that reverses the control flow in traditional programming. In the traditional programming model, the dependencies between components are created and maintained internally by the components themselves. In the Inversion of Control model, this dependency is managed by an external container (such as the Spring framework, Microsoft.Extensions.DependencyInjection in .NET, etc.), and the components are no longer responsible for their own dependencies, but inject the required dependencies through external containers.

main idea: Moves the creation of objects and the management of dependencies between them from the objects themselves to external containers.

advantage

  • Reduce coupling: The dependencies between components are no longer hard-coded, so component implementations can be replaced more easily, improving the flexibility and maintainability of the system.
  • Improve modularity: Individual components can be developed and tested independently because they do not depend on specific implementations but on abstract interfaces or abstract classes.
  • Easy to test: Because the dependencies between components are externalized, it is easier to use mock objects or test stubs to simulate dependencies for unit testing.

Dependency Injection (DI)

definition: Dependency injection is a specific way to implement inversion of control. It involves passing dependencies (services or objects) into a class instead of having the class create them itself.

Method to realize

  • Constructor Injection: Provide dependencies through the class's constructor. This is the most common and recommended form of DI in C#.
  • Property Injection: Assign dependencies through public properties of the class. This approach provides flexibility but may expose internal state and reduce encapsulation.
  • Method Injection: Dependencies are passed through method parameters. This is suitable for injecting only the dependencies required by a specific method.

IOC Container

definition:The IOC container is a framework for managing object lifecycles and dependencies. It automatically creates objects based on configurations (such as XML files, annotations, or code configurations) and injects dependencies into these objects.

effect

  • Object creation: Automatically create object instances based on configuration.
  • Dependency Injection: Inject dependencies into objects to achieve inversion of control.
  • Lifecycle Management: Manage the life cycle of objects, including creating, destroying and recycling resources.

Use IOC containers to manage dependencies

In C#, you can use a variety of IOC containers to manage dependencies, such as Microsoft.Extensions.DependencyInjection (the built-in DI container in .NET Core and later versions), Autofac, etc. The following takes Microsoft.Extensions.DependencyInjection as an example to introduce how to use IOC containers to manage dependencies in C# projects.

Step 1: Register the service

Services are usually in the .NET applicationProgram.csorStartup.cs(For ASP.NET Core projects)IServiceCollectionInterface registration.

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IMyService, MyService>(); // 将MyService注册为单例服务
    // 其他服务注册
}
  • 1
  • 2
  • 3
  • 4
  • 5
Step 2: Inject dependencies

Inject dependencies in controllers, services or any other class through constructor.

public class MyController : Controller
{
    private readonly IMyService _myService;

    public MyController(IMyService myService)
    {
        _myService = myService;
    }

    // ... 控制器的其他代码
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

In the above example,MyControllerThe class is injected through the constructorIMyServiceImplementation of the interface (i.e.MyServiceclass). Thus, whenMyControllerWhen created, the IOC container automaticallyIMyServiceThe implementation is injected into the constructor.

Precautions
  • Use interface-based abstraction: Prefer interfaces or abstract classes for dependency types to enhance flexibility and testability.
  • Avoid overuse of singletons: Singleton services should be used with caution to avoid state-related issues.
  • Monitoring object life cycle: Understand the lifecycle of dependencies (singleton, scoped, transient) to effectively manage resource usage.