ServiceContainer (WIP) - removed params in Resolve

This commit is contained in:
Daniele Teti 2024-03-27 00:24:00 +01:00
parent cf2450465b
commit 9035aed2e7

View File

@ -12,7 +12,7 @@ type
IMVCServiceContainer = interface
['{1BB3F4A8-DDA1-4526-981C-A0BF877CFFD5}']
function RegisterType(const aImplementation: TClassOfInterfacedObject; const aInterface: TGUID; const aName : string = ''; const aRegType: TRegistrationType = rtTransient): IMVCServiceContainer; overload;
function Resolve(const aTypeInfo: PTypeInfo; const aName: string = ''; const aParams: TArray<TValue> = nil): IInterface;
function Resolve(const aTypeInfo: PTypeInfo; const aName: string = ''): IInterface;
procedure Build();
end;
@ -41,6 +41,7 @@ type
TRegistration = class
Intf: TGUID;
Clazz: TClassOfInterfacedObject;
RttiType: TRttiType;
Instance: IInterface;
RegistrationType: TRegistrationType;
end;
@ -61,8 +62,8 @@ type
class destructor Destroy;
function RegisterType<TImpl: TInterfacedObject>(const aInterface: TGUID; const aName : string = ''; const aRegType: TRegistrationType = rtTransient): IMVCServiceContainer; overload;
function RegisterType(const aImplementation: TClassOfInterfacedObject; const aInterface: TGUID; const aName : string = ''; const aRegType: TRegistrationType = rtTransient): IMVCServiceContainer; overload;
function Resolve<TIntf: IInterface>(const aName: string = ''; const aParams: TArray<TValue> = nil): TIntf; overload;
function Resolve(const aTypeInfo: PTypeInfo; const aName: string = ''; const aParams: TArray<TValue> = nil): IInterface; overload;
function Resolve<TIntf: IInterface>(const aName: string = ''): TIntf; overload;
function Resolve(const aTypeInfo: PTypeInfo; const aName: string = ''): IInterface; overload;
procedure Build();
end;
@ -136,24 +137,27 @@ end;
function TMVCServiceContainer.RegisterType(const aImplementation: TClassOfInterfacedObject; const aInterface: TGUID;
const aName: string; const aRegType: TRegistrationType): IMVCServiceContainer;
var
lType: TRttiType;
lReg: TRegistration;
begin
if fBuilt then
begin
raise EMVCContainerError.Create('Cannot register new service if the container has been already built');
end;
lType := TRttiUtils.GlContext.GetType(aImplementation);
if Supports(aImplementation, aInterface) then
begin
lReg := TRegistration.Create;
lReg.Clazz := aImplementation;
lReg.RttiType := TRttiUtils.GlContext.GetType(lReg.Clazz);
lReg.RegistrationType := aRegType;
fRegistry.Add(GetKey(aInterface, aName), lReg);
if not fRegistry.TryAdd(GetKey(aInterface, aName), lReg) then
begin
raise EMVCContainerError.CreateFmt('Cannot register duplicated service "%s"',[GetKey(aInterface, aName)]);
end;
end
else
begin
raise EMVCContainerErrorUnknownService.Create(lType.Name + ' doesn''t supports requested interface');
raise EMVCContainerErrorUnknownService.CreateFmt('"%s" doesn''t supports requested interface', [aImplementation.QualifiedClassName]);
end;
Result := Self;
end;
@ -163,8 +167,7 @@ begin
Result := RegisterType(TImpl, aInterface, aName, aRegType);
end;
function TMVCServiceContainer.Resolve(const aTypeInfo: PTypeInfo; const aName: string;
const aParams: TArray<TValue>): IInterface;
function TMVCServiceContainer.Resolve(const aTypeInfo: PTypeInfo; const aName: string): IInterface;
var
lReg: TRegistration;
lTypeInfo: PTypeInfo;
@ -173,14 +176,14 @@ var
begin
if not fBuilt then
begin
raise EMVCContainerError.Create('Cannot resolve service if the container has not been built');
raise EMVCContainerError.Create('Container has not been built');
end;
lTypeInfo := aTypeInfo;
if not fRegistry.TryGetValue(GetKey(lTypeInfo.TypeData.GUID, aName), lReg) then
begin
raise EMVCContainerErrorUnknownService.CreateFmt('Unknown service "%s" with name "%s"', [lTypeInfo.Name, aName])
end;
lType := TRttiUtils.GlContext.GetType(lReg.Clazz);
lType := lReg.RttiType;
case lReg.RegistrationType of
rtTransient:
@ -197,7 +200,7 @@ begin
try
if lReg.Instance = nil then
begin
lService := TRttiUtils.CreateObject(lType, AParams);
lService := CreateServiceWithDependencies(lReg.Clazz, TRttiUtils.GetFirstDeclaredConstructor(lType));
Supports(lService, lTypeInfo.TypeData.GUID, lReg.Instance)
end;
finally
@ -211,9 +214,9 @@ begin
end;
end;
function TMVCServiceContainer.Resolve<TIntf>(const aName: string; const aParams: TArray<TValue>): TIntf;
function TMVCServiceContainer.Resolve<TIntf>(const aName: string): TIntf;
begin
Result := Resolve(TypeInfo(TIntf), aName, aParams);
Result := Resolve(TypeInfo(TIntf), aName);
end;
procedure TMVCServiceContainer.Build;