我想在我正在编写的类中查询一些属性(也就是注释)。
我可以用复杂的方式来做,但我想改用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的书)?
答案 0 :(得分:3)
这些过滤器是使用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>
。