- changed status to resolved
Exception when injecting nil values to a complex constructor via the DI-container
Issue #366
resolved
Hi,
We are trying to inject an empty value to a constructor via the DI container. Doing so, the TCreationContext fails to resolve the correct constructor though, resulting in an EActivatorException.
The error can be reproduced with code like this (see the attached project file for complete code):
type
IMyInterface = interface
['{10422B97-B488-4F2A-852C-0ED1724F2D45}']
end;
TMyClass = class(TInterfacedObject, IMyInterface)
constructor Create(const pDependency: IMyInterface; const pSomething: String);
end;
{ IMyClass }
constructor TMyClass.Create(const pDependency: IMyInterface; const pSomething: String);
begin
inherited Create();
end;
begin
GlobalContainer.RegisterType<IMYInterface, TMyClass>;
GlobalContainer.Build;
// This works.
var lDep1: IMyInterface := TMyClass.Create(nil, '');
var lRes1: IMyInterface := GlobalContainer.Resolve<IMyInterface>([TValue.From<IMyInterface>(lDep1), 'random']);
// This raises an EActivatorException
var lDep2: IMyInterface := nil;
var lRes2: IMyInterface := GlobalContainer.Resolve<IMyInterface>([TValue.From<IMyInterface>(lDep2), 'random']);
end.
We know we can resolve this by adjusting the order of the parameters and adding overloaded constructors without the nil parameters. This requires additional code though and is not intuitive to use at all, as parameters passed to the resolve-method remain unused.
A possible fix may be not to treat empty values as any type in Spring.Container.CreationContext.TCreationContext.AddArgument:
function TCreationContext.AddArgument(const argument: TValue): Integer;
begin
fLock.BeginWrite;
try
if argument.IsType<TTypedValue>(False) then
Result := fTypedArguments.Add(argument)
else if argument.IsType<TNamedValue>(False) then
Result := fNamedArguments.Add(argument)
else
Result := fArguments.Add(argument);
finally
fLock.EndWrite
end;
end;
Thank you!
Daniel
Comments (1)
-
repo owner - Log in to comment
I cannot repro this in develop - it has been fixed by the commit for
#336.