unit Demo.Manager;
interface
uses
System.Classes,
System.Generics.Collections,
Demo.Interfaces;
TYPE
TManagerEntry =
Record
TheClass : TClass;
TheInst : TObject;
End;
MyManager =
Class
private
class var fClasses:TDictionary<
STRING,TManagerEntry>;
protected
Class Constructor Create;
Class Destructor Destroy;
Public
Class Procedure RegisterEntry(Ident:
String;AClass:TClass);
Class function GetEntry(Ident:
String):ITestInterface;
End;
implementation
uses
System.TypInfo,
System.RTTI,
System.SysUtils,
Demo.Classes;
Class Constructor MyManager.Create;
begin
fclasses := TDictionary<
STRING,TManagerEntry>.create;
end;
Class Destructor MyManager.Destroy;
begin
fclasses.free;
end;
Class Procedure MyManager.RegisterEntry(ident:
string;AClass:TClass);
var
tmp : TManagerEntry;
begin
if (fclasses.containsKey(ident))
then
Raise Exception.Create(ident+'
is already registered !');
if (Supports(AClass,ITestInterface))
then
begin
tmp.TheClass := AClass;
tmp.TheInst :=
NIL;
fclasses.add(ident,tmp);
end;
end;
Class function MyManager.GetEntry(ident:
string):ITestInterface;
var
hlp : TManagerEntry;
function CreateMyIntf(AClass:TClass):TObject;
var
ctx: TRttiContext;
RT: TRttiType;
Value: TValue;
RM: TRttiMethod;
ParamList: TList<TValue>;
RP: TRttiParameter;
begin
result :=
NIL;
ctx := TRttiContext.Create;
RT := ctx.GetType(AClass);
for rm
in rt.GetMethods
do
begin
if rm.IsConstructor
then
begin
ParamList := TList<TValue>.Create;
for rp
in rm.GetParameters
do
begin
TValue.Make(0, rp.ParamType.Handle, Value);
ParamList.Add(Value);
end;
result := rm.Invoke(AClass,ParamList.ToArray).AsObject;
ParamList.Free;
break;
end;
end;
end;
begin
result :=
NIL;
if (fclasses.ContainsKey(ident))
then
begin
hlp := fclasses[ident];
if (hlp.TheInst =
NIL)
then
hlp.TheInst := CreateMyIntf(hlp.TheClass);
Supports(hlp.TheInst,ITestInterface,result);
end;
end;
end.