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

如何为每个IAnimal实现类注入独立的HostedService实例?

问题描述

希望运行多个HostedService,每个实例注入一个IAnimal实现类,确保每个IAnimal实现类都对应一个独立的HostedService实例。当前实现方式不够优雅,寻求更优方案。

当前实现代码

AnimalDependencyResolver.cs

public interface IDependencyResolver<out TResolve>
{
    TResolve GetDependency();
}

public class AnimalDependencyResolver : IDependencyResolver<IAnimal>
{
    private int _currentIndex = 0;
    private readonly int _animalCount = 0;
    private readonly IEnumerable<IAnimal> _animals;

    public AnimalDependencyResolver(IEnumerable<IAnimal> animals)
    {
        _animals = animals;
        _animalCount = _animals.Count();
    }

    public IAnimal GetDependency()
    {
        if (_animalCount <= 0 || _currentIndex >= _animalCount)
            throw new InvalidOperationException("Sequence contains no (more) elements");

        return _animals.ElementAt(_currentIndex++);
    }
}

Program.cs

services.AddSingleton<IHostedService, AnimalService>();
services.AddSingleton<IHostedService, AnimalService>();
services.AddSingleton<IHostedService, AnimalService>();
services.AddSingleton<IHostedService, AnimalService>();
services.AddSingleton<IHostedService, AnimalService>();
services.AddScoped<IAnimal, MajesticSeaFlapFlap>();    
services.AddScoped<IAnimal, TrashPanda>();
services.AddScoped<IAnimal, FartSquirrel>();
services.AddScoped<IAnimal, DangerFloof>();
services.AddScoped<IAnimal, NopeRope>();
services.AddSingleton<IDependencyResolver<IAnimal>, AnimalDependencyResolver>();

AnimalService.cs

public AnimalService(ILogger<AnimalService> logger, IDependencyResolver<IAnimal> animalResolver)
{
    _logger = logger;
    _animal = animalResolver.GetDependency();
}

优化方案

方案1:工厂模式自动注册对应实例

去掉冗余的IDependencyResolver,让AnimalService直接依赖IAnimal,通过反射遍历所有IAnimal实现类,自动注册对应的HostedService实例。

修改AnimalService

public class AnimalService : IHostedService
{
    private readonly ILogger<AnimalService> _logger;
    private readonly IAnimal _animal;

    public AnimalService(ILogger<AnimalService> logger, IAnimal animal)
    {
        _logger = logger;
        _animal = animal;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation($"启动 {_animal.GetType().Name} 对应的服务");
        // 此处添加业务逻辑
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation($"停止 {_animal.GetType().Name} 对应的服务");
        // 此处添加清理逻辑
        return Task.CompletedTask;
    }
}

自动注册逻辑(Program.cs)

// 获取当前程序集中所有实现IAnimal的非抽象类
var animalTypes = Assembly.GetExecutingAssembly()
    .GetTypes()
    .Where(t => typeof(IAnimal).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface);

foreach (var animalType in animalTypes)
{
    // 注册当前IAnimal实现类
    services.AddScoped(animalType);

    // 为每个IAnimal实现类创建并注册对应的AnimalService实例
    services.AddSingleton<IHostedService>(sp =>
    {
        var logger = sp.GetRequiredService<ILogger<AnimalService>>();
        var animal = (IAnimal)sp.GetRequiredService(animalType);
        return new AnimalService(logger, animal);
    });
}

方案2:泛型HostedService

定义泛型AnimalHostedService<TAnimal>,每个泛型实例对应一个具体的IAnimal实现,通过反射自动完成注册。

定义泛型HostedService

public class AnimalHostedService<TAnimal> : IHostedService where TAnimal : IAnimal
{
    private readonly ILogger<AnimalHostedService<TAnimal>> _logger;
    private readonly TAnimal _animal;

    public AnimalHostedService(ILogger<AnimalHostedService<TAnimal>> logger, TAnimal animal)
    {
        _logger = logger;
        _animal = animal;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation($"启动 {typeof(TAnimal).Name} 对应的服务");
        // 此处添加业务逻辑
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation($"停止 {typeof(TAnimal).Name} 对应的服务");
        // 此处添加清理逻辑
        return Task.CompletedTask;
    }
}

自动注册逻辑(Program.cs)

var animalTypes = Assembly.GetExecutingAssembly()
    .GetTypes()
    .Where(t => typeof(IAnimal).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface);

foreach (var animalType in animalTypes)
{
    // 注册当前IAnimal实现类
    services.AddScoped(animalType);

    // 创建泛型HostedService类型并注册
    var hostedServiceType = typeof(AnimalHostedService<>).MakeGenericType(animalType);
    services.AddSingleton<IHostedService>(hostedServiceType);
}

方案优势

  • 无需手动重复注册HostedService,新增IAnimal实现类时自动生效,减少维护成本
  • 去掉冗余的解析器,依赖关系更直接,符合依赖注入设计原则
  • 每个HostedService实例明确对应一个IAnimal实现,逻辑清晰,便于调试维护

内容的提问来源于stack exchange,提问作者Starfish

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 21:45:34