如何在Spring4d中使用THasAttributeFilter?

3
我想查询我正在编写的类中的一些属性(也称为注释)。虽然我可以通过复杂的方式实现,但我想使用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代码(例如Nick Hodges的书中所述)?


你的属性行中有一些错别字,编辑器不允许我们更改,因为它们似乎太微不足道了。你可能需要编辑一下它们。 - David Schwartz
@DavidSchwartz 属性可以使用在编译时可以评估的任何内容,不仅限于“整数和数字”。此外,Embarcadero自己并没有将属性前缀命名为 T。没有人说它们“必须”以 T 开头。 - Günther the Beautiful
@DavidSchwartz,修正了拼写错误。不过你需要加强对属性的理解,可以看一下这个链接:http://www.malcolmgroves.com/blog/?p=476 - Johan
谢谢你们的建议,伙计们! - David Schwartz
1个回答

4
这些过滤器是使用规格模式实现的。请参见Spring.DesignPatterns.pas。
当您需要像IEnumerable.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>成为可能。
使用规范模式会导致非常可读和可组合的代码,因为您保持所有内容分开。循环不会混杂在内部,以确定它是否是构造函数或方法具有哪些参数,因为每个规范都封装在自己的类中。
附注:Methods是来自Spring.Helpers的TRttiTypeHelper的属性,返回IEnumerable<TRttiMethod>

谢谢Stefan,TPredicate的使用看起来真的很酷。我猜这是因为匿名方法中发生的参数捕获而起作用的?也就是说,在D7中这将无法工作,但在XE中可以。 - Johan
是的,在Spring4D支持的所有版本中(2010年及以上版本)都可以。 - Stefan Glienke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接