跨不同项目调用类避免循环引用的可行实现方案咨询
可行解决方案整理
轻量方案(无需新增项目,优先级最高)
直接在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
相关产品推荐
相关产品推荐

