Сканирование всех классов на предмет заданного пользовательского атрибута - PullRequest
3 голосов
/ 29 февраля 2012

Я ищу способ сканирования всех загруженных классов для классов, которые содержат пользовательский атрибут, если это возможно, без использования RegisterClass ().

Ответы [ 2 ]

7 голосов
/ 29 февраля 2012

сначала вы должны создать TRttiContext, а затем получить все загруженные классы, используя getTypes. после этого вы можете фильтровать типы по TypeKind = tkClass; Следующий шаг - перечислить атрибуты и проверить, есть ли у них ваш атрибут;

атрибут и тестовый класс:

unit Unit3;

interface
type
    TMyAttribute = class(TCustomAttribute)
    end;

    [TMyAttribute]
    TTest = class(TObject)

    end;

implementation

initialization
    TTest.Create().Free();  //if class is not actually used it will not be compiled

end.

и найдите его:

program Project3;
{$APPTYPE CONSOLE}

uses
  SysUtils, rtti, typinfo, unit3;

type TMyAttribute = class(TCustomAttribute)

     end;

var ctx : TRttiContext;
    t : TRttiType;
    attr : TCustomAttribute;
begin
    ctx := TRttiContext.Create();

    try
        for t  in ctx.GetTypes() do begin
            if t.TypeKind <> tkClass then continue;

            for attr in t.GetAttributes() do begin
                if attr is TMyAttribute then begin
                    writeln(t.QualifiedName);
                    break;
                end;
            end;
        end;
    finally
        ctx.Free();
        readln;
    end;
end.

вывод Unit3.TTest

Вызовите RegisterClass, чтобы зарегистрировать класс в системе потоковой передачи .... Как только классы зарегистрированы, они могут быть загружены или сохранены системой потоковой передачи компонентов.

поэтому, если вам не нужна потоковая передача компонента (просто найдите классы с некоторым атрибутом), вам не нужно RegisterClass

4 голосов
/ 29 февраля 2012

Вы можете использовать новую функциональность RTTI, предоставляемую устройством Rtti.

var
  context: TRttiContext;
  typ: TRttiType;
  attr: TCustomAttribute;
  method: TRttiMethod;
  prop: TRttiProperty;
  field: TRttiField;
begin
  for typ in context.GetTypes do begin
    for attr in typ.GetAttributes do begin
      Writeln(attr.ToString);
    end;

    for method in typ.GetMethods do begin
      for attr in method.GetAttributes do begin
        Writeln(attr.ToString);
      end;
    end;

    for prop in typ.GetProperties do begin
      for attr in prop.GetAttributes do begin
        Writeln(attr.ToString);
      end;
    end;

    for field in typ.GetFields do begin
      for attr in field.GetAttributes do begin
        Writeln(attr.ToString);
      end;
    end;
  end;
end;

Этот код перечисляет атрибуты, связанные с методами, свойствами и полями, а также с типами. Естественно, вы захотите сделать больше, чем Writeln(attr.ToString), но это должно дать вам представление о том, как действовать дальше. Вы можете проверить свой специфический атрибут обычным способом

if attr is TMyAttribute then
  ....
...