I'm struggling with StructureMap. I need to ensure that i get an instance per HttpContextLifecycle but one for each constructor parameter. Our old working code was:
Registry:
For<IGenericFormInitialValueResolver<SalesforceEditContactBlock>>()
.LifecycleIs<HttpContextLifecycle>()
.Use<SalesforceEditFormInitialValueResolver>();
In FormInitialValueResolverFactory(actualType is the IGenericFormInitialValueResolver generic type):
if (_iocContainer.TryGetInstance(actualType) is IGenericFormInitialValueResolver returnValue)
{
if (returnValue is ISalesforceInstanceFormInitialValueResolver salesforceInstanceFormInitialValueResolver &&
salesforceInstanceName.HasValue)
{
salesforceInstanceFormInitialValueResolver.SalesforceInstanceName = salesforceInstanceName.Value;
}
return returnValue;
}
Now i need to change it, so that the SalesforceInstanceName is given in the constructor. But i still want that for each SalesforceInstanceName(it's an enum with 2 values) the instance is cached for the HttpContextLifecycle. So i passed the parameter via TryGetInstance overload:
ExplicitArguments args = new ExplicitArguments();
args.Set(salesforceInstanceName ?? SalesforceInstanceName.Undefined);
if (_iocContainer.TryGetInstance(actualType, args) is IGenericFormInitialValueResolver returnValue)
{
return returnValue;
}
That worked in a way that i got the instance but always a new one, so it's not cached per http lifecycle.
So i have tried to change the registry:
foreach (SalesforceInstanceName salesforceInstanceName in (SalesforceInstanceName[])Enum.GetValues(typeof(SalesforceInstanceName)))
{
For<IGenericFormInitialValueResolver<SalesforceEditContactBlock>>()
.Add<SalesforceEditFormInitialValueResolver>().Ctor<SalesforceInstanceName>()
.Is(salesforceInstanceName)
.LifecycleIs<HttpContextLifecycle>();
}
But now TryGetInstance always returns null.
StructureMap by design will always build a fresh instance if you pass custom constructor parameters via
ExplicitArguments. You might want to use named instances instead like this:You basically say that for each value of
SalesforceInstanceNameenum you register separate named instance (with name of said enum value) ofSalesforceEditFormInitialValueResolverwith that enum value as constructor argument.Then to resolve, instead of using
ExplicitArguments, use name: