unit Bcl.Rtti.ObjectFactory;

{$I bcl.inc}

interface

type
  IObjectFactory = interface
  ['{1C8ADF49-BB87-4CF5-A566-C4F46CBA4442}']
    function CreateInstance(AClass: TClass): TObject;
  end;

  TObjectFactory = class(TInterfacedObject, IObjectFactory)
  protected
    function CreateInstanceWithRtti(AClass: TClass): TObject;
  public
    function CreateInstance(AClass: TClass): TObject;
  end;

implementation

uses
  Rtti;

function TObjectFactory.CreateInstance(AClass: TClass): TObject;
begin
  Result := CreateInstanceWithRtti(AClass);
end;

function TObjectFactory.CreateInstanceWithRtti(AClass: TClass): TObject;
var
  C: TRttiContext;
  RttiType: TRttiType;
  Method: TRttiMethod;
begin
  C := TRttiContext.Create;
  try
    RttiType := C.GetType(AClass);
    for Method in RttiType.GetMethods do
    begin
      if Method.IsConstructor and (Length(Method.GetParameters) = 0) then
        Exit(Method.Invoke(AClass, []).AsObject);
    end;
    Result := nil;
  finally
    C.Free;
  end;
end;

end.

