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

跨不同项目调用类避免循环引用的可行实现方案咨询

可行解决方案整理

轻量方案(无需新增项目,优先级最高)

直接在Website层给BaseReq定义扩展方法,利用Website已引用Models的现有依赖关系,完全避免循环引用:

  • 先在Website项目注册IHttpContextAccessor服务(ASP.NET Core内置类型,用于安全访问当前请求上下文)
    // Program.cs 中添加
    builder.Services.AddHttpContextAccessor();
    
  • 定义BaseReq的扩展方法,封装你的Header填充逻辑:
    public static class BaseReqHeaderExtensions
    {
        private static IHttpContextAccessor _accessor;
        public static void UseHttpContextAccessor(IHttpContextAccessor accessor) => _accessor = accessor;
    
        public static T FillHeader<T>(this T request) where T : BaseReq
        {
            var context = _accessor.HttpContext;
            // 调用你原有Initialize方法的逻辑填充Header属性
            request.Header.SiteId = context?.Request.Headers["SiteId"].FirstOrDefault();
            request.Header.Currency = context?.Items["Currency"]?.ToString();
            // 其余通用属性赋值逻辑
            return request;
        }
    }
    
  • 程序启动时给扩展方法传入IHttpContextAccessor实例,后续所有Request实例化后直接链式调用即可,不需要每次写重复的填充代码:
    var req = new GetCustomersRequest
    {
        // 业务参数赋值
    }.FillHeader();
    

解耦方案(适合多端复用场景,新增共享项目)

如果你的Models项目需要给Website之外的其他项目(比如桌面客户端、定时任务服务)复用,选择这个方案:

  • 新建共享类库项目Common.Abstractions,Website和Models都引用这个项目
  • 在Common.Abstractions中定义IHeaderInitializer接口,声明填充方法签名:
    public interface IHeaderInitializer
    {
        void Fill(BaseReq req);
    }
    
  • 在Website项目中实现这个接口,实现类中可以直接访问HttpContext和原有Initialize方法
  • 给BaseReq添加静态的Initializer属性,类型为IHeaderInitializer,Website启动时给这个属性赋值为实现类的实例
  • 后续BaseReq的构造函数中直接调用Initializer?.Fill(this)即可自动完成填充,不需要上层调用时手动处理

注意:禁止在Models项目中直接依赖访问HttpContext,会导致Models层和Web环境强绑定,无法在非Web场景下复用,也破坏了分层设计的单一职责原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:45:10