I'm using Spring4D's dependency injector in something organized as MVP, in my view I have the interface reference of my presenter and in the create method of the presenter I have the injection of the view's interface in the constructor, the view is registered as a singleton, however, when creating and resolving the Presenter, the view is created again and enters a loop, is it possible to do this with Spring4D?
procedure RegisterTypes(const Container: TContainer);
begin
Container.RegisterType<TConexao>.asSingleton;
Container.RegisterType<TConversorService>;
Container.RegisterType<TfrmConversorView>.AsSingleton();
Container.RegisterType<TConversorUseCase>;
container.Build;
end;
My View(Form)
type
TfrmConversorView = class(TForm, IConversorView)
JvStatusBar1: TJvStatusBar;
procedure FormShow(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
FService: IConversorService;
{ Private declarations }
public
{ Public declarations }
end;
...
procedure TfrmConversorView.FormCreate(Sender: TObject);
begin
FService := GlobalContainer.Resolve<IConversorService>;
end;
My Presenter
Type
TConversorService = Class(TInterfacedObject, IConversorService)
Private
FView: IConversorView;
FUseCase: IConversorUseCase;
Public
Constructor Create(aView: IConversorView; aUseCase: IConversorUseCase);
End;
implementation
{ TConversorService }
Constructor TConversorService.Create(aView: IConversorView; aUseCase: IConversorUseCase);
begin
FView := aView;
FUseCase := aUseCase;
end;
Tks.
I imagined that declaring as a singleton the existing instance of the object would be injected instead of creating a new one,
CodePudding user response:
The issue is that you do service location which is a different Resolve chain from the one originally creating the view. That causes another creation of the TConversorService
which is not marked as singleton.
Design your code as if you were doing pure DI - tinkering with the DI container without proper design and then stuffing service location into your code always leads to issues.
If you need a back reference to your IConversorService
inside the view that gets injected into your IConversorService
then the easiest way is to put a property onto your view which can be set inside of TConversorService.Create
.