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

StructureMap同一接口多构造参数实例按HttpContextLifecycle缓存问题

问题根源

  1. 使用ExplicitArguments传参时,StructureMap会默认绕过生命周期缓存,每次强制生成新实例,因此第一次尝试无法复用同HttpContext下的实例。
  2. 遍历注册时仅用Add()注册多实例,既未指定默认实例也未给实例加唯一标识,TryGetInstance默认只会匹配默认实例,因此返回空值。

解决方案一(命名实例方案,适配遍历注册思路)

第一步:修改Registry注册逻辑,给每个枚举对应的实例加唯一名称

foreach (SalesforceInstanceName salesforceInstanceName in (SalesforceInstanceName[])Enum.GetValues(typeof(SalesforceInstanceName)))
{
    For<IGenericFormInitialValueResolver<SalesforceEditContactBlock>>()
        .Use<SalesforceEditFormInitialValueResolver>()
        .Ctor<SalesforceInstanceName>().Is(salesforceInstanceName)
        .Named(salesforceInstanceName.ToString()) // 按枚举值作为实例唯一标识
        .LifecycleIs<HttpContextLifecycle>();
}

第二步:修改Factory获取逻辑,按名称匹配对应实例

var targetInstanceName = salesforceInstanceName ?? SalesforceInstanceName.Undefined;
if (_iocContainer.TryGetInstance(actualType, targetInstanceName.ToString()) is IGenericFormInitialValueResolver returnValue)
{
    return returnValue;
}

解决方案二(上下文工厂方案,适配动态泛型场景)

如果需要适配多种泛型类型的IGenericFormInitialValueResolver<>,不需要逐个遍历枚举注册,改用上下文绑定的工厂注册即可:

// 注册时绑定HttpContext上下文取值逻辑
For<IGenericFormInitialValueResolver<SalesforceEditContactBlock>>()
    .LifecycleIs<HttpContextLifecycle>()
    .Use(context =>
    {
        var instanceName = HttpContext.Current.Items["CurrentSalesforceInstance"] as SalesforceInstanceName?
            ?? SalesforceInstanceName.Undefined;
        return new SalesforceEditFormInitialValueResolver(instanceName);
    });

调用前先把当前请求对应的枚举值存入HttpContext.Items:

HttpContext.Current.Items["CurrentSalesforceInstance"] = salesforceInstanceName;
var resolver = _iocContainer.TryGetInstance(actualType);

内容的提问来源于stack exchange,提问作者Tim Schmelter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 05:54:03