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

Castle Windsor:如何跨不同执行时间的组件图共享临时对象?

解决不同执行时机组件间临时对象共享的方案

嘿,针对你提到的遗留状态引擎(每个IState负责生成下一个状态,会话上下文带GUID,还有静态的CreatedCount/DisposedCount追踪问题),我整理了几个贴合你场景的实用方案:

1. 给会话上下文加个“共享对象仓库”(最适配现有架构)

既然每个状态已经持有会话上下文,那直接把需要共享的临时对象挂载到上下文里就好,完全不用改动现有状态流转的核心逻辑:

  • 扩展你的SessionContext类,加一个SharedTempObjects字典,用来存会话级的临时对象
  • 在创建临时对象的状态里,把对象存入字典,用唯一标识当键(比如结合会话GUID+对象类型,避免冲突)
  • 后续状态从上下文字典里取出对象,用完可以直接移除,避免内存浪费

示例代码片段:

// 扩展后的会话上下文
public class SessionContext
{
    public Guid SessionId { get; set; }
    // 会话专属的临时对象仓库
    public Dictionary<string, object> SharedTempObjects { get; } = new();
    // 替换静态计数的会话级计数
    public int CreatedCount { get; set; }
    public int DisposedCount { get; set; }
}

// 在生成临时对象的初始状态里
public class InitialState : IState
{
    public IState NextState(SessionContext context)
    {
        var tempObj = new YourTempObject();
        // 用唯一键存入仓库
        var key = $"{context.SessionId}_Temp_{typeof(YourTempObject).Name}";
        context.SharedTempObjects.Add(key, tempObj);
        
        // 更新会话级创建计数
        context.CreatedCount++;
        
        // 继续流程...
        return new FollowUpState();
    }
}

// 在后续状态里使用临时对象
public class FollowUpState : IState
{
    public IState NextState(SessionContext context)
    {
        var key = $"{context.SessionId}_Temp_{typeof(YourTempObject).Name}";
        if (context.SharedTempObjects.TryGetValue(key, out var obj) 
            && obj is YourTempObject tempObj)
        {
            // 这里用临时对象做业务逻辑
            DoSomethingWithTempObj(tempObj);
            
            // 用完清理,同时更新销毁计数
            context.SharedTempObjects.Remove(key);
            context.DisposedCount++;
        }
        // 继续流转...
        return null;
    }
}

这个方案完美适配你现有的状态引擎架构,还解决了静态计数的问题——每个会话的计数独立,不会像全局静态变量那样跨会话混乱,线程安全也更容易保证。

2. 用Scoped服务托管临时对象(适合重构场景)

如果你有计划慢慢重构遗留代码,可以把需要共享的临时对象封装成Scoped服务:

  • 把临时对象做成接口+实现类,比如ITempSharedService和TempSharedService
  • 在DI容器里把它注册为Scoped生命周期(和会话生命周期绑定)
  • 每个状态通过构造函数注入这个服务,同一会话内的所有状态都会拿到同一个实例

注意:要确保你的状态实例也是Scoped的,或者DI容器能正确识别会话范围,不然会拿到不同的实例。

3. 异步/跨场景用消息队列传递(复杂场景备选)

如果你的状态执行是异步的,甚至跨进程运行,那可以把临时对象序列化后存入消息队列,用会话GUID作为标识:

  • 序列化临时对象(比如用Json.NET或System.Text.Json)
  • 存队列时带上会话ID作为键
  • 后续状态根据会话ID从队列里拉取对象,用完删除

不过这个方案复杂度高,适合分布式的复杂场景,一般小项目用不上。

关于静态计数的额外建议

你提到的CreatedCount和DisposedCount静态变量,因为是全局共享的,不仅会串会话数据,还容易有线程安全问题。建议改成:

  • 在SessionContext里加专属的计数属性,每个会话自己维护
  • 或者用静态字典,键是会话GUID,值是该会话的计数对象(比如Dictionary<Guid, SessionCounts>)

这样就能准确追踪每个会话的对象创建/销毁情况了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:09:09