【问题标题】:How do I use THasAttributeFilter in Spring4d如何在 Spring4d 中使用 THasAttributeFilter
【发布时间】:2014-07-16 15:09:55
【问题描述】:

我想查询我正在编写的类中的一些属性(也称为注解)。

我可以用复杂的方式来做,但我想改用 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 的书)所需的无数行?

【问题讨论】:

  • 您在属性行中有一些错别字,编辑器不允许我们更改,因为它们显然太琐碎了。您可能想要编辑它们。
  • @DavidSchwartz 属性可以包含可以在编译时评估的所有内容,而不仅仅是“整数和数字”。此外,Embarcadero 本身不使用 T 为属性添加前缀。没有人说他们“必须”以 T 开头
  • @DavidSchwartz,修正了错字。不过你需要复习一下属性,看看:malcolmgroves.com/blog/?p=476
  • 感谢您的提示,伙计们!

标签: delphi attributes spring4d


【解决方案1】:

这些过滤器是使用Specification Pattern 实现的。 另请参阅 Spring.DesignPatterns.pas。

当您需要 IEnumerable&lt;T&gt;.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&lt;T&gt;,然后可以将其传递给 Where 方法。

每个 TMethodFilters 返回的 TSpecification&lt;T&gt; 是一个带有运算符重载的记录,这使得布尔逻辑并将其分配给 TPredicate&lt;T&gt; 成为可能。

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

附: Methods 是来自 Spring.Helpers 的 TRttiTypeHelper 的一个属性,它返回 IEnumerable&lt;TRttiMethod&gt;

【讨论】:

  • 感谢 Stefan,TPredicate 的使用看起来确实很酷。我认为它之所以有效,是因为匿名方法中发生的参数捕获? IE。这在 D7 中不起作用,但在 XE 中会起作用。
  • 是的,在 Spring4D(2010 及更高版本)支持的所有版本中。
猜你喜欢
  • 1970-01-01
  • 2016-10-27
  • 1970-01-01
  • 1970-01-01
  • 2017-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-01
相关资源
最近更新 更多