.NET依赖注入之一个接口多个实现


在.NET Core 中,实现一个接口有多个具体实现(multiple implementations)是一种常见的需求,特别是在需要根据不同条件或配置使用不同实现时。依赖注入容器(Dependency Injection Container)可以很好地支持这种场景,以下是一种常用的方法:

步骤概述

  1. 定义接口和多个实现类

    首先定义一个接口,并创建多个实现类。例如:

    public interface IService
    {
        void Execute();
    }
    
    public class ServiceA : IService
    {
        public void Execute()
        {
            Console.WriteLine("Service A executed.");
        }
    }
    
    public class ServiceB : IService
    {
        public void Execute()
        {
            Console.WriteLine("Service B executed.");
        }
    }
    
    public class ServiceC : IService
    {
        public void Execute()
        {
            Console.WriteLine("Service C executed.");
        }
    }
    
  2. 注册服务

    Startup.cs 文件的 ConfigureServices 方法中,注册接口和其对应的实现类。在.NET Core 中,可以通过 AddTransientAddScopedAddSingleton 方法进行注册,具体选择取决于服务的生命周期和应用的需求。

    public void ConfigureServices(IServiceCollection services)
    {
        // 注册 ServiceA
        services.AddTransient<IService, ServiceA>();
    
        // 注册 ServiceB
        services.AddTransient<IService, ServiceB>();
    
        // 注册 ServiceC
        services.AddSingleton<IService, ServiceC>();
    
        // 可以根据需要注册不同的生命周期
    }
    

    注意:注册时,如果使用相同的接口多次调用 AddTransientAddScopedAddSingleton,则后面注册的实现类会覆盖前面的实现类。

  3. 使用注入的服务

    在需要使用服务的地方,通过依赖注入将服务注入到类的构造函数中或通过属性注入。

    public class MyController : ControllerBase
    {
        private readonly IService _service;
    
        public MyController(IService service)
        {
            _service = service;
        }
    
        public IActionResult Index()
        {
            _service.Execute();
            return Ok();
        }
    }
    

    在上述例子中,MyController 控制器中的 _service 将根据依赖注入容器提供的配置选择合适的实现(例如 ServiceAServiceBServiceC)。

  4. 选择特定实现

    如果需要在注册时选择特定的实现,可以使用命名注册或条件注册。例如,使用 AddTransient 的重载版本来提供一个 key 或者 type 。

    public void ConfigureServices(IServiceCollection services)
    {
        // 通过 key 或者 type 实现服务注册
        services.AddTransient<IService>(serviceProvider =>
        {
            var configuration = serviceProvider.GetRequiredService<IConfiguration>();
            var serviceType = configuration["ServiceType"];
    
            switch (serviceType)
            {
                case "ServiceA":
                    return new ServiceA();
                case "ServiceB":
                    return new ServiceB();
                default:
                    return new ServiceC();
            }
        });
    }
    

通过这些步骤,你可以在.NET Core 中有效地管理一个接口多个实现的情况,并根据需要选择适当的实现。这种灵活性使得在应用程序中根据不同的条件或配置轻松地切换和使用不同的服务实现。


原文链接:codingdict.net