Zwischenzeitlich woanders weitergebaut, bin heute wieder drüber gestolpert.
Hab mir folgendes überlegt. Man kann doch methoden oder constructors auch über die
RTTI aufrufen.
Damit hätte ich genau was ich ursprünglich wollte....
Ein Beispiel hab ich
hier gefunden:
Delphi-Quellcode:
Function NewFromClassInfo(
Const ATypeInfo: PTypeInfo;
{Params: Array Of Tvalue}): Tobject;
Var
Ctx: TRttiContext;
RType: TRttiType;
AMethCreate: TRttiMethod;
InstanceType: TRttiInstanceType;
Fvalue:
Rtti.Tvalue;
Begin
Ctx := TRttiContext.Create;
RType := Ctx.GetType(ATypeInfo);
For AMethCreate
In RType.GetMethods
Do
Begin
{$MESSAGE 'TODO Handle constructors with params.'}
If Assigned(AMethCreate)
Then
If (AMethCreate.IsConstructor)
And
(Length(AMethCreate.GetParameters) = 0)
//müsste dann entfernt werden
Then
Begin
InstanceType := RType.AsInstance;
FValue := AMethCreate.Invoke(InstanceType.MetaclassType, [
{params}]);
{hatte überlegt, params hier zu übergeben. das führt jedoch zu access violation
ODER zur meldung ("parameter count mismatch").
Und JA, ich übergebe (nur anscheinend) die richtige parameterzahl.
(Also wenn create(anint:integer)>>tx.create(5);
>>newfromclassinfo(tx.classinfo,[5]);
}
Result := Fvalue.AsObject;
Exit;
End;
End;
End;
Kann man das verbessern? Obiges beheben?
Merci.
Hier mal ein kleines Beispiel:
Delphi-Quellcode:
program Simple_DI;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
SimpleContainer in 'SimpleContainer.pas';
type
IX = interface
['{E2D88E1C-AE7D-491A-B456-84B134749890}']
end;
IY = interface
['{3D1256AB-CDDE-49B2-94CF-E9FA82314206}']
end;
IZ = interface
['{4F51DE5D-B65B-4776-B25B-5B2868DC34AC}']
end;
TX = class(TInterfacedObject, IX)
private
fy: IY;
fz: IZ;
public
constructor Create(const y: IY; const z: IZ);
end;
TY = class(TInterfacedObject, IY)
constructor Create;
end;
TZ = class(TInterfacedObject, IZ)
constructor Create;
end;
{ TX }
constructor TX.Create(const y: IY; const z: IZ);
begin
Writeln('creating ', ClassName);
Writeln('injected ', (y as TObject).ClassName, ' for y');
Writeln('injected ', (z as TObject).ClassName, ' for z');
fy := y;
fz := z;
end;
{ TY }
constructor TY.Create;
begin
Writeln('creating ', ClassName);
end;
{ TZ }
constructor TZ.Create;
begin
Writeln('creating ', ClassName);
end;
var
container: TSimpleContainer;
x: IX;
begin
// showing the so called register, resole, release (RRR) pattern
// see http://blog.ploeh.dk/2010/09/29/TheRegisterResolveReleasepattern/
container := TSimpleContainer.Create;
try
// register
container.Add<IX, TX>;
container.Add<IY, TY>;
container.Add<IZ, TZ>;
// resolve
x := container.Get<IX>;
finally
// release
x := nil;
container.Free;
end;
end.