C#中如何跨类访问Controller类的公开属性
跨类访问控制器属性的正确实现
你当前场景的核心问题是错误选择了传递整个控制器实例的方案,既提高了代码耦合度,也不符合ASP.NET Core的框架设计约定,以下是两种可行实现,优先推荐第一种:
方案1:构造函数直接传递目标值(推荐)
不需要传递整个控制器实例,只需要把你实际需要用到的ISReadCol布尔值作为参数传入QueryResult即可,这是耦合最低、最易维护的实现方式。
- 修改
QueryResult类,新增本地字段存储传入的布尔值,调整构造函数参数:
class QueryResult : ActionResult { private readonly ILogger log; private readonly ConnectionPoolEntry poolEntry; private readonly bool _isReadCol; public QueryResult(ConnectionPoolEntry poolEntry, ILogger log, bool isReadCol) { this.log = log; this.poolEntry = poolEntry; _isReadCol = isReadCol; } public override async Task ExecuteResultAsync(ActionContext context) { // 直接读取本地存储的_isReadCol即可使用 // 你的业务逻辑 } }
- 修改控制器中[1]标记处的
QueryResult实例化代码,传入当前属性值:
private async Task<IActionResult> GetQueryResult(string database) { // 其他业务代码 return new QueryResult(pool, log, ISReadCol); }
你之前提到修改[1]处代码"无法正常生效",本质是因为你尝试传入整个控制器实例带来了额外的生命周期依赖问题,只传递需要的值不存在这类问题,是标准实现方式。
方案2:从ActionContext解析控制器实例(不推荐)
如果你不想修改构造函数传参,可以通过ExecuteResultAsync方法自带的ActionContext参数解析当前请求的控制器实例,但是这种方式和具体控制器类型强耦合,兼容性差,仅适合临时快速适配场景:
public override async Task ExecuteResultAsync(ActionContext context) { if (context.ActionDescriptor is ControllerActionDescriptor controllerDesc) { var controller = context.HttpContext.RequestServices .GetRequiredService(controllerDesc.ControllerTypeInfo) as QueryController; if (controller != null) { bool isReadCol = controller.ISReadCol; // 拿到值后执行业务逻辑 } } }
注意:该方案如果在非
QueryController的其他控制器中返回QueryResult,会出现类型转换失败拿不到值的问题,长期维护的项目不要用这种写法。
内容的提问来源于stack exchange,提问作者abhishek
相关产品推荐
相关产品推荐

