"Unsatisfied constructor" on constructor injection with Spring4D

Viewed 712

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.

1 Answers
Related