You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET依赖注入实现多态:如何按需注册服务实现类?

ASP.NET依赖注入(DI)多实现场景的服务注册与调用方案

当IService同时有WaterService和ElectricService两个实现,需要根据不同路由返回对应服务信息时,有以下几种实用方案:

方案1:直接注册具体实现类,控制器分支处理

这种方式简单直接,适合场景不复杂的情况:

1. 注册具体服务

在Program.cs中将两个实现类直接注册到DI容器:

using DependencyInjectionSample.Interfaces;
using DependencyInjectionSample.Services;
var builder = WebApplication.CreateBuilder(args);

// 注册两个具体服务实例
builder.Services.AddScoped<WaterService>();
builder.Services.AddScoped<ElectricService>();

var app = builder.Build();

2. 控制器注入并分支调用

创建ServiceController,注入两个具体服务,根据路由分别返回对应信息:

public class ServiceController : ControllerBase
{
    private readonly WaterService _waterService;
    private readonly ElectricService _electricService;

    public ServiceController(WaterService waterService, ElectricService electricService)
    {
        _waterService = waterService;
        _electricService = electricService;
    }

    [HttpGet("service/waterService")]
    public IActionResult GetWaterInfo()
    {
        // 假设IService有GetInfo()方法返回服务信息
        return Ok(_waterService.GetInfo());
    }

    [HttpGet("service/electricService")]
    public IActionResult GetElectricInfo()
    {
        return Ok(_electricService.GetInfo());
    }
}

方案2:用工厂模式封装服务选择逻辑

如果希望基于IService接口统一处理,避免直接依赖具体实现类,可以用工厂模式封装选择逻辑:

1. 定义服务工厂

创建工厂接口和实现类,负责根据标识获取对应服务:

public interface IServiceFactory
{
    IService GetService(string serviceType);
}

public class ServiceFactory : IServiceFactory
{
    private readonly IServiceProvider _serviceProvider;

    public ServiceFactory(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public IService GetService(string serviceType)
    {
        return serviceType switch
        {
            "waterService" => _serviceProvider.GetRequiredService<WaterService>(),
            "electricService" => _serviceProvider.GetRequiredService<ElectricService>(),
            _ => throw new ArgumentException("无效的服务类型")
        };
    }
}

2. 注册服务与工厂

在Program.cs中注册两个实现类和工厂:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddScoped<WaterService>();
builder.Services.AddScoped<ElectricService>();
builder.Services.AddScoped<IServiceFactory, ServiceFactory>();

var app = builder.Build();

3. 控制器通过工厂获取服务

public class ServiceController : ControllerBase
{
    private readonly IServiceFactory _serviceFactory;

    public ServiceController(IServiceFactory serviceFactory)
    {
        _serviceFactory = serviceFactory;
    }

    [HttpGet("service/{serviceType}")]
    public IActionResult GetServiceInfo(string serviceType)
    {
        try
        {
            var service = _serviceFactory.GetService(serviceType);
            return Ok(service.GetInfo());
        }
        catch (ArgumentException ex)
        {
            return BadRequest(ex.Message);
        }
    }
}

方案3:使用.NET 8+的Keyed Services特性

如果项目基于.NET 8或更高版本,可以用官方新增的Keyed Services特性,直接给服务绑定标识:

1. 注册带Key的服务

在Program.cs中指定每个实现对应的Key:

var builder = WebApplication.CreateBuilder(args);

// 给两个实现分别绑定Key
builder.Services.AddKeyedScoped<IService, WaterService>("water");
builder.Services.AddKeyedScoped<IService, ElectricService>("electric");

var app = builder.Build();

2. 控制器中获取对应Key的服务

可以通过IServiceProvider获取指定Key的服务,或者用[FromKeyedServices]特性直接注入:

public class ServiceController : ControllerBase
{
    private readonly IServiceProvider _serviceProvider;

    public ServiceController(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    [HttpGet("service/waterService")]
    public IActionResult GetWaterInfo()
    {
        var waterService = _serviceProvider.GetRequiredKeyedService<IService>("water");
        return Ok(waterService.GetInfo());
    }

    [HttpGet("service/electricService")]
    public IActionResult GetElectricInfo()
    {
        var electricService = _serviceProvider.GetRequiredKeyedService<IService>("electric");
        return Ok(electricService.GetInfo());
    }
}

内容的提问来源于stack exchange,提问作者Ma Việt Tùng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 11:01:02