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

.NET Core中不通过构造函数注入获取已注入服务实例的方法

非构造注入获取IFw_UsersRepository实例的实现方案

你当前的场景下,不需要在构造函数注入IFw_UsersRepository即可获取实例,有以下3种可落地的实现方式:

方案1:通过DI容器按需解析(推荐)

这是最符合.NET依赖注入规范的非构造注入方案,不会破坏DI的生命周期管理:

  1. 首先在Program.cs中注册HttpContext访问器:
    builder.Services.AddHttpContextAccessor();
    
  2. 仅在构造函数中注入IHttpContextAccessor,在需要用到仓储的方法内部,通过当前请求的服务容器按需解析实例即可,修改后的代码如下:
    public class WorkingCredential
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        public WorkingCredential(dynamic me, IHttpContextAccessor httpContextAccessor)
        {
            UserId = me.UserId;
            _httpContextAccessor = httpContextAccessor;
        }
        public WorkingCredential()
        {
        }
    
        public string UserId { get; set; }
        public bool IsInRole(string _ruleName)
        {         
            // 方法执行时按需解析仓储实例
            var userRepository = _httpContextAccessor?.HttpContext?.RequestServices
                .GetService<IFw_UsersRepository>();
            if (userRepository == null) return false;
            var userRoles = userRepository.GetUserRolls();
            // 注意:你原有逻辑未匹配传入的_ruleName,只要有角色就返回true,实际使用请补充角色名校验
            return userRoles.Any();
        }
    }
    

如果完全不能修改现有构造函数的签名,可以临时用静态服务定位器实现,但这属于DI反模式,仅做兼容用:

// 先定义静态服务定位器
public static class ServiceLocator
{
    public static IServiceProvider RootProvider { get; set; }
}

// Program.cs中构建完应用后赋值
// var app = builder.Build();
// ServiceLocator.RootProvider = app.Services;

// 在IsInRole方法中用作用域解析,避免Scoped服务内存泄漏
// using var scope = ServiceLocator.RootProvider.CreateScope();
// var userRepository = scope.ServiceProvider.GetRequiredService<IFw_UsersRepository>();
// var userRoles = userRepository.GetUserRolls();
// return userRoles.Any();

方案2:方法参数传参(零依赖,测试友好)

如果调用IsInRole方法的位置可以直接拿到IFw_UsersRepository实例,直接把仓储作为方法参数传入即可,不需要在类中持有私有字段,耦合度最低,单元测试时可以直接传入Mock对象:

public bool IsInRole(string _ruleName, IFw_UsersRepository userRepository)
{         
    if (userRepository == null) return false;
    var userRoles = userRepository.GetUserRolls();
    return userRoles.Any();
}

方案3:手动实例化依赖(仅临时调试用,不推荐生产)

如果只是临时调试用,可以在方法内部手动构造AppDbContext和对应仓储的实例,但这种方式完全脱离DI容器管理,需要硬编码数据库配置,后续仓储新增依赖时必须同步修改此处代码,维护成本极高:

public bool IsInRole(string _ruleName)
{
    var optionsBuilder = new DbContextOptionsBuilder<AppDbContext>();
    // 此处数据库配置必须和启动项中注册的配置完全一致
    optionsBuilder.UseSqlServer("你的数据库连接字符串");
    using var dbContext = new AppDbContext(optionsBuilder.Options);
    // Fw_UsersRepository替换为你项目中IFw_UsersRepository的实际实现类名
    var userRepository = new Fw_UsersRepository(dbContext);
    var userRoles = userRepository.GetUserRolls();
    return userRoles.Any();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:36:22