首页 > 解决方案 > StructureMap 用于相同的接口,但具有用于不同构造函数参数的多个实例

问题描述

我正在为 StructureMap 苦苦挣扎。我需要确保我得到一个实例,HttpContextLifecycle但每个构造函数参数都有一个。我们的旧工作代码是:

注册表:

For<IGenericFormInitialValueResolver<SalesforceEditContactBlock>>()
    .LifecycleIs<HttpContextLifecycle>()
    .Use<SalesforceEditFormInitialValueResolver>();

FormInitialValueResolverFactory(actualType 是IGenericFormInitialValueResolver泛型类型):

if (_iocContainer.TryGetInstance(actualType) is IGenericFormInitialValueResolver returnValue)
{
    if (returnValue is ISalesforceInstanceFormInitialValueResolver salesforceInstanceFormInitialValueResolver &&
        salesforceInstanceName.HasValue)
    {
        salesforceInstanceFormInitialValueResolver.SalesforceInstanceName = salesforceInstanceName.Value;
    }
    return returnValue;
}

现在我需要更改它,以便SalesforceInstanceName在构造函数中给出。但我仍然希望为每个SalesforceInstanceName(它是一个具有 2 个值的枚举)实例缓存HttpContextLifecycle. 所以我通过TryGetInstance重载传递了参数:

ExplicitArguments args = new ExplicitArguments();
args.Set(salesforceInstanceName ?? SalesforceInstanceName.Undefined);
if (_iocContainer.TryGetInstance(actualType, args) is IGenericFormInitialValueResolver returnValue)
{
    return returnValue;
}

这以一种我得到实例但总是一个新实例的方式起作用,因此它不会在每个 http 生命周期中缓存。

所以我试图改变注册表:

foreach (SalesforceInstanceName salesforceInstanceName in (SalesforceInstanceName[])Enum.GetValues(typeof(SalesforceInstanceName)))
{
    For<IGenericFormInitialValueResolver<SalesforceEditContactBlock>>()
        .Add<SalesforceEditFormInitialValueResolver>().Ctor<SalesforceInstanceName>()
        .Is(salesforceInstanceName)
        .LifecycleIs<HttpContextLifecycle>();
}

但现在TryGetInstance总是回归null

标签: c#dependency-injectionstructuremap

解决方案


如果您通过ExplicitArguments. 您可能希望像这样使用命名实例:

foreach (SalesforceInstanceName salesforceInstanceName in (SalesforceInstanceName[])Enum.GetValues(typeof(SalesforceInstanceName)))
{
    For<IGenericFormInitialValueResolver<SalesforceEditContactBlock>>()
        .Use<SalesforceEditFormInitialValueResolver>()
        .Ctor<SalesforceInstanceName>()
        .Is(salesforceInstanceName)
        .Named(salesforceInstanceName.ToString())
        .LifecycleIs<HttpContextLifecycle>();
}

您基本上说,对于枚举的每个值,您使用该枚举值作为构造函数参数SalesforceInstanceName注册单独的命名实例(具有所述枚举值的名称) 。SalesforceEditFormInitialValueResolver

然后解决,而不是使用ExplicitArguments,使用名称:

container.TryGetInstance(actualType, salesforceInstanceName.ToString());

推荐阅读