I'm struggling with the constructor injection of Spring4D. In a certain class i want to inject a specific implementation (by name) of an interface into the constructor.
Look at this:
IListFactory = interface
['{40...29}']
function GetList : IListOfSomething;
end;
ICiderPress = interface
['{50...10}']
procedure Press;
end;
TAppleListFactory = class(TInterfacedObject, IListFactory)
function GetList : IListOfSomething;
end;
TCiderPress = class(TInterfacedObject, ICiderPress)
private
FListFactory : IListFactory;
public
constructor Create(const ListFactory : IListFactory);
procedure Press;
end;
implementation
function TCiderPress.Create(const ListFactory : IListFactory);
begin
FListFactory := ListFactory;
end;
procedure TCiderPress.Press;
begin
// Do somtihing with FListFactory
end;
initialization
GlobalContainer.RegisterType<TAppleListFactory>.Implements<IListFactory>('apple');
GlobalContainer.RegisterType<TCiderPress>.Implements<ICiderPress>;
end.
Now I get an instance of my press with the ServiceLocator:
CiderPress := ServiceLocator.GetService<ICiderPress>;
CiderPress.Press;
and it works fine.
Now I add a second ListFactory:
TOrangeListFactory = class(TInterfacedObject, IListFactory)
function GetList : IListOfSomething;
end;
and add the registration
GlobalContainer.RegisterType<TOrangeListFactory>.Implements<IListFactory>('orange');
and change my cidre press class to
TCiderPress = class(TInterfacedObject, ICiderPress)
private
FListFactory : IListFactory;
public
[Inject]
constructor Create([Inject('apple')]const ListFactory : IListFactory);
procedure Press;
end;
The Problem is, that the ctor of TCiderPress is not called.
If I add
GlobalContainer.AddExtension<TActivatorContainerExtension>;
I get an EActivatorException: Unsatisfied contructor on type: TCiderPress
What's going wrong?
EDIT:
It works, if i delegate the construction like this:
GlobalContainer.RegisterType<TCiderPress>.Implements<ICiderPress>
.DelegateTo(function : TCiderPress
begin
Result := TCiderPress.Create(ServiceLocator.GetService<IListFactory>('apple');
end
);
EDIT2:
I found my error! I had to include Spring.Container.Common in the interface uses clause.
I'm using Delphi XE3 and Spring4D 1.1.3.