Я борюсь с конструкторской инъекцией Spring4D. В определенном классе я хочу ввести конкретную реализацию (по имени) интерфейса в конструктор.«Неудовлетворенный конструктор» при впрыске конструктора с Spring4D
Посмотрите на это:
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.
Теперь я получаю экземпляр моей печати с ServiceLocator:
CiderPress := ServiceLocator.GetService<ICiderPress>;
CiderPress.Press;
и она отлично работает.
Теперь я добавить второй ListFactory:
TOrangeListFactory = class(TInterfacedObject, IListFactory)
function GetList : IListOfSomething;
end;
и добавить в регистрирующий
GlobalContainer.RegisterType<TOrangeListFactory>.Implements<IListFactory>('orange');
и изменить свой сидр пресс-класс
TCiderPress = class(TInterfacedObject, ICiderPress)
private
FListFactory : IListFactory;
public
[Inject]
constructor Create([Inject('apple')]const ListFactory : IListFactory);
procedure Press;
end;
Проблема в том, что т е р из TCiderPress не вызывается.
Если добавить
GlobalContainer.AddExtension<TActivatorContainerExtension>;
Я получаю EActivatorException: Неудовлетворенный застройщик по типу: TCiderPress
Что идет не так?
EDIT:
Это работает, если я делегировать строительство так:
GlobalContainer.RegisterType<TCiderPress>.Implements<ICiderPress>
.DelegateTo(function : TCiderPress
begin
Result := TCiderPress.Create(ServiceLocator.GetService<IListFactory>('apple');
end
);
EDIT2:
Я нашел ошибку! Я должен был включить Spring.Container.Common в интерфейсе использует пункт.
Я использую Delphi XE3 и Spring4D 1.1.3.
Похоже, нам нужен [mcve] –
пример из @mezen работает для меня. Мое настоящее приложение довольно сложно. Я пытаюсь воспроизвести ошибку с минимальным примером. До тех пор, есть ли способ отлаживать инъекцию конструктора? – Mik
Все может быть отлажено. Создание репродукции - это то, как я его отлаживал. –