You are not logged in.
Pages: 1
How to properly declare interfaces to permit a dependency injection in interface based services?
UserService.pas
IUserService = interface(IInvokable)
['{A8C05236-F397-4422-9201-E676AB82F380}']
function Read(ID: TID; out User: TSQLUser): boolean;
end;
TUserService = class(TInterfacedObject, IUserService)
private
fUserRepository: IUserRepository;
public
constructor Create(aUserRepository: IUserRepository); reintroduce;
function Read(ID: TID; out User: TSQLUser): boolean;
end;
initialization
TInterfaceFactory.RegisterInterfaces([
TypeInfo(IUserService)
]);
UserRepository.pas
IUserRepository = interface(IInvokable)
['{D4AF2ABB-5D53-43CA-8403-EC4A65BB76C4}']
function Read(ID: TID; out User: TSQLUser): boolean;
end;
TUserRepository = class(TInterfacedObject, IUserRepository)
private
fRest: TSQLRest;
public
constructor Create(aRest: TSQLRest); reintroduce;
function Read(ID: TID; out User: TSQLUser): boolean;
end;
initialization
TInterfaceFactory.RegisterInterfaces([
TypeInfo(IUserRepository)
]);
Main.pas
...
aServer := TSQLRestServerDB.Create(lModel, SQLITE_MEMORY_DATABASE_NAME);
aServer.ServiceDefine(TUserService, [IUserService], sicShared);
...
The reintroduced Create constructors never called and the Read function raising exception 'fRepository is nil' . Only works a manual injection: aServer.ServiceDefine(TUserService.Create(TUserRepository.Create(aServer), [IUserService]), but I think it's not the right solution.
Offline
This constructor should be override, not reintroduced.
Otherwise, you should create instance by hand, then register it using overloaded version of ServiceDefine(aSharedImplementation, [aInterfaces])
Edit 2022 01 24 1556
Wired DI features are implemented in REST part of the code, not SOA part.
regards
Last edited by uian2000 (2022-01-24 07:58:34)
Offline
See TInjectableObjectRest.
Offline
This constructor should be override, not reintroduced.
One can override only the same ancestor method. If the method was declared with a different parameters it can be only overload or reintroduce.
See TInjectableObjectRest.
Switching to TInjectableObjectRest seems to work
TUserService = class(TInterfacedObjectRest, IUserService)
...
constructor TUserService.Create;
begin
inherited Create;
Assert(Server.Services.Resolve(IUserRepository, fUserRepository),'IUserRepository object not found');
end;
But what I'm looking for is automated DI
Offline
One can override only the same ancestor method. If the method was declared with a different parameters it can be only overload or reintroduce.
You are right.
See TInjectableObjectRest.
This is quite the answser.
More over, you can inherite your service from TInjectableObjectRest, then override the constructor CreateWithResolverAndRest.
This way DI automaticly processed when you define interface implementation.
Regards.
Offline
TInjectableObjectRest works if declared with ServiceDefine, but this way a useless root/interfacename/{method} entry points were created. I tried TInterfaceResolverInjected.RegisterGlobal so dependable classes can find and create the object, but Rest is not injected anymore in created object (Create called instead of CreateWithResolverAndRest).
TUserService.UserRepository created and TUserService.UserRepository.Server injected, but root/userrepository/{method} service's entry points declared.
TUserRepository = class(TInjectableObjectRest, IUserRepository)
...
TUserService = class(TInjectableObject, IUserService)
private
fUserRepository: IUserRepository;
published
property UserRepository: IUserRepository read fUserRepository write fUserRepository;
...
aServer.ServiceDefine(TUserRepository, [IUserRepository], sicShared);
aServer.ServiceDefine(TUserService, [IUserService], sicShared);
TUserService.UserRepository created, but TUserService.UserRepository.Server is nil
TInterfaceResolverInjected.RegisterGlobal(TypeInfo(IUserRepository),TUserRepository);
aServer.ServiceDefine(TUserService, [IUserService], sicShared);
How to register a TInjectableObjectRest class with a proper auto Rest injection and avoiding a useless entry points creation?
Offline
Pages: 1