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

如何让IEnumerable<IRepository>与特定仓储接口注入同一实例?

问题描述

现有仓储接口与实现类结构如下:

public interface IRepository
{
    public Task PreLoadData();
}

public interface IUserRepository : IRepository
{
    public List<User> Users { get; }
    // 其他实例专属方法
}

public class UserRepository : IUserRepository
{
    public List<User> Users { get; private set; }

    public async Task PreLoadData()
    {
        Users = await GetUsers();
    }
}

同时需要通过DataPreLoader统一预加载数据:

public class DataPreLoader
{
    private IEnumerable<IRepository> _repositories;

    public DataPreLoader(IEnumerable<IRepository> repositories)
    {
        _repositories = repositories;
    }

    public async Task PreloadAllData()
    {
        foreach(var repository in _repositories)
        {
            await repository.PreLoadData();
        }
    }
}

遇到的问题:

  • 若使用services.AddScoped<IRepository, UserRepository>()注册,IEnumerable<IRepository>与IUserRepository能被注入,但二者是不同实例:调用IEnumerable<IRepository>中实例的PreLoadData()后,后续注入的IUserRepository并未加载数据。
  • 若使用services.AddScoped<IUserRepository, UserRepository>()注册,IEnumerable<IRepository>为空,无法通过DataPreLoader预加载数据。

需要实现的目标:确保IEnumerable<IRepository>接收的实例与注入IUserRepository时的实例为同一个。


解决方案

要让两个接口共享同一个实例,需在DI容器中明确将IRepository和IUserRepository关联到同一个UserRepository实例,具体有两种实现方式:

方式1:先注册实现类,再映射接口

services.AddScoped<UserRepository>();
services.AddScoped<IRepository>(sp => sp.GetRequiredService<UserRepository>());
services.AddScoped<IUserRepository>(sp => sp.GetRequiredService<UserRepository>());

这种方式下,DI容器会先创建UserRepository的Scoped实例,后续无论是请求IRepository、IUserRepository还是IEnumerable<IRepository>,都会返回这个已创建的实例(在当前Scoped生命周期内)。

方式2:基于已注册的接口映射

services.AddScoped<IUserRepository, UserRepository>()
        .AddScoped<IRepository>(sp => sp.GetRequiredService<IUserRepository>());

先完成IUserRepository到UserRepository的注册,再将IRepository指向已注册的IUserRepository实例,确保两个接口共享同一个实例。


原理说明
  • 直接单独注册某一个接口时,DI容器会将每个接口视为独立的服务类型,即使它们指向同一个实现类,也会创建不同的实例。
  • 通过显式指定实例来源(从容器中获取已注册的实现类/接口实例),可以强制多个接口共享同一个实例,解决预加载后数据不共享的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:52:31