Delphi 如何在Spring4d中使用THasAttributeFilter

Delphi 如何在Spring4d中使用THasAttributeFilter,delphi,attributes,spring4d,Delphi,Attributes,Spring4d,我想查询我正在编写的类中的一些属性(又名注释) 我可以用复杂的方式来做,但我想用Spring4D来代替 它有一个叫做反射的单元,看起来像是我需要的,但我不知道如何使用它 我在网上看过,但是没有关于如何使用这个单元的例子 我发现: THasAttributeFilter 看起来是这样的: THasAttributeFilter<T: TRttiObject> = class(TMemberSpecificationBase<T>) private fAt

我想查询我正在编写的类中的一些属性(又名注释)

我可以用复杂的方式来做,但我想用Spring4D来代替

它有一个叫做反射的单元,看起来像是我需要的,但我不知道如何使用它

我在网上看过,但是没有关于如何使用这个单元的例子

我发现:

THasAttributeFilter 
看起来是这样的:

  THasAttributeFilter<T: TRttiObject> = class(TMemberSpecificationBase<T>)
  private
    fAttributeClass: TAttributeClass;
  protected
    function Accept(const member: T): Boolean; override;
  public
    constructor Create(attributeClass: TAttributeClass);
  end;
我可以创建一个HasAttributeFilter,如下所示:

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;
HasAttr:= THasAttributeFilter<TMyClass>.Create(CapabilitiesAttribute);
... ?? now what ??
HasAttr:=THasAttributeFilter.Create(CapabilitiesAttribute);
... ?? 现在怎么办??

如何使用Spring4D测试属性,而不必编写经典RTTI编写(例如,根据Nick Hodges的书)所需的无数行?

这些过滤器是使用。 另请参见Spring.DesignPatterns.pas

它们在需要委托时使用,如
IEnumerable.Where()
方法中的委托

以下是从Spring4D本身(Spring.Container.Builder)截取的代码:

var
条件:t预测;
方法:trtti法;
...
开始
条件:=TMethodFilters.IsInstanceMethod
和TMethodFilters.HasAttribute(InjectAttribute)
而不是TMethodFilters.HasParameterFlags([pfOut,pfVar])
而不是TMethodFilters.IsConstructor;
对于model.ComponentType.Methods.Where(条件)do中的方法
...
您可以看到,不同的规范可以与布尔逻辑结合起来形成一个表达式:方法必须是实例方法,并且必须具有InjectAttribute,不能有out或var参数,并且不应该是构造函数

然后可以将此组合规范分配给
t预测
,然后将其传递给Where方法

每个tMethodFilter返回的
t指定
是一个带有运算符重载的记录,这使得布尔逻辑成为可能,并将其分配给一个
t预测

使用规范模式会产生非常可读和可组合的代码,因为您将所有内容分开。由于每个规范都封装在自己的类中,因此循环不会与如何确定其是否为构造函数或方法具有何种类型的参数的内部结构混淆


p.S.
Methods
是Spring.Helpers中的
trttityhelper
属性,它返回
IEnumerable

属性行中有一些键入错误,编辑器不允许我们更改,因为它们显然太琐碎了。您可能需要编辑它们。@DavidSchwartz属性可以提供编译时可以计算的所有内容,而不仅仅是“整数和数字”。此外,Embarcadero本身不使用
t
作为属性前缀。没有人说他们“必须”从一个
T
@DavidSchwartz开始,修正了拼写错误。不过,你需要温习一下属性,看看:谢谢你们的提示,伙计们!谢谢Stefan,TPredicate的用法看起来确实很酷。我想它之所以能工作是因为匿名方法中的参数捕获?也就是说,这在D7中不起作用,但在XE中会起作用。是的,在Spring4D(2010及更高版本)支持的所有版本中都会起作用。
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
    ...