delphi 如何在Spring4d中使用THasAttributeFilter

5t7ly7z5  于 12个月前  发布在  Spring
关注(0)|答案(1)|浏览(85)

我想在我正在编写的类中查询一些属性(也称为注解)。
我可以用复杂的方法来实现,但我想用Spring4D来代替。
它有一个名为Reflection的单元,看起来它有我需要的东西,但我不知道如何使用它。
我在网上找过,但是没有关于如何使用这个单元的例子。
我发现:

THasAttributeFilter

它看起来像这样:

THasAttributeFilter<T: TRttiObject> = class(TMemberSpecificationBase<T>)
  private
    fAttributeClass: TAttributeClass;
  protected
    function Accept(const member: T): Boolean; override;
  public
    constructor Create(attributeClass: TAttributeClass);
  end;

很好,我创建了一个过滤器,如下所示:

type
  Capability = (CanDoA, CanDoB);
  TCapabilities = set of Capability;

[Capabilities(CanDoA)]
TMyClass = class(TParent)
strict private
  class var fCapabilities: TCapabilities;
....
public
  property Capabilities: TCapabilities read GetCapabilities;
end;

我可以像这样创建一个HasAttributeFilter:

HasAttr:= THasAttributeFilter<TMyClass>.Create(CapabilitiesAttribute);
... ?? now what ??

我如何使用Spring4D来测试属性,而不必编写经典RTTI编写的无数行(例如,尼克·霍奇斯的书中提到的

toiithl6

toiithl61#

这些过滤器使用Specification Pattern实现。另请参见Spring.DesignPatterns.pas。
当你需要像IEnumerable<T>.Where()方法那样的委托时,它们会被使用。
下面是Spring4D本身的代码片段(Spring.Container.Builder):

var
  condition: TPredicate<TRttiMethod>;
  method: TRttiMethod;
  ...
begin
  condition := TMethodFilters.IsInstanceMethod
    and TMethodFilters.HasAttribute(InjectAttribute)
    and not TMethodFilters.HasParameterFlags([pfOut, pfVar])
    and not TMethodFilters.IsConstructor;
  for method in model.ComponentType.Methods.Where(condition) do
    ...

可以看到,不同的规范可以与布尔逻辑组合在一起,形成一个表达式:方法必须是一个示例方法,必须有InjectAttribute,不能有out或var参数,也不应该是一个构造函数。
然后,可以将这个组合的规范分配给TPredicate<T>,然后将其传递给Where方法。
每个TMethodFilters返回的TSpecification<T>是一个带有运算符重载的记录,这使得布尔逻辑和将其分配给TPredicate<T>成为可能。
使用规范模式会产生可读性和可组合性都很好的代码,因为你把所有的东西都分开了。循环不会因为内部的东西而变得混乱,比如如何确定它是否是一个构造函数,或者方法有什么类型的参数,因为每个规范都封装在自己的类中。
P.S. Methods是Spring.Helpers中TRttiTypeHelper的一个属性,它返回IEnumerable<TRttiMethod>

相关问题