2 Eylül 2013 Pazartesi

Rtti Gevşek Unitler :)

Bir projedeki unit'lerin uses bloglarına baktığımızda bir sürü unit ismi görürüz.

Bunların bir çoğu da projeye bizim eklediğimiz unit dosyalarıdır.

Ve hepsi birbirine bağlıdır.Bu bağımlığı en aza indirmenin yollarından birisi de ,reflection kullanmaktır. :)

Aşağıda yazacağım rttiFormActivator methodu ile bir "unitismi.formsınıfadı" vererek formu oluşturmak için kullanabiliriz.

Bu method kullanıma göre özelleştirebilir.

function  rttiFormActivator(typeQualifiedName : string; isModal:Boolean=false) : TValue;
var
 context      : TRttiContext;
 rttTyp       : TRttiType;
 instanceType : TRttiInstanceType;
 instance     : TValue;
begin

 try
   context   := TRttiContext.Create();
   rttTyp    := context.FindType(typeQualifiedName);

   instanceType := rttTyp.AsInstance;
   instance     := instanceType.GetMethod('Create').Invoke(instanceType.MetaclassType,[nil]) ;

   Result := instance;

   case isModal of
      true  :   instanceType.GetMethod('ShowModal').Invoke(instance,[]);
      false :   instanceType.GetMethod('Show').Invoke(instance,[]);
   end;

 except on E: Exception do
   raise Exception.Create(typeQualifiedName+ ' Tipi register edilmemiş !');
 end;

end;
Unit1.pas dosyanın uses bloğuna kullanmak istediğimiz herhangi bir unit içersindeki formun unitini tanımlamadan direk aşağıdaki kullanılabilecektir.
procedure TForm1.btnShowForm2Click(Sender: TObject);
begin
  rttiFormActivator('Unit2.TForm2',true);
end;


procedure TForm1.btnShowForm3Click(Sender: TObject);
begin
  rttiFormActivator('Unit3.TForm3');
end;
unit1.pas'ın uses bloğuna unit2,unit3 eklemeyerek,bu unitlere bağlı olmasını engellemiş ve dinamik bir kullanım elde etmiş olduk. Yanlız şöyle önemli bir durum var. Kullanacağınız sınıflarını register etmediğiniz zaman rtti amca findType methodu ile ilgili verdiğiniz tipi bulamıyor. o yüzden sınıfları bulunduğu unit içinde register ederek,findType methodu ile bulmasını sağlayabiliriz.
initialization
 RegisterClass(TForm2);

finalization
 UnRegisterClass(TForm2);


Kaynak Kod : https://github.com/ismailkocacan/Rtti-Loose-Coupling-Units

iyi çalışmalar.