这是我第二次尝试解释我试图完成的事情,因为我以前没有解释得很好。
对于这个伪例子,如果你有类来解决安装如下;
TOuter.constructor.Create(Name: TName; Inner1, Inner2: TInner);
TInner.constructor.Create(Name: TName; Sub: TSub);
TSub.constructor.Create(Name: TName);
TName.constructor.Create(Name: String);
var Names = TStack<String>.Create;
如果可以在解析之前和之后进行拦截,则可以实现父代、祖先或“正在为……构造我”。
例如
RegisterType<TName>(
function: TName
begin
Result:=TName.Create(String.Join('.',Names.List.ToArray));
end
);
RegisterType<TOuter>;
RegisterType<TInner>;
RegisterType<TSub>;
Resolver.BeforeResolve:=
procedure(ClassType: TClass)
begin
Names.Push(ClassType.ClassName);
end;
Resolver.AfterResolve:=
procedure(ClassType: TClass)
begin
Names.Pop;
end;
Resolve<TOuter> would produce
TOuter
Name = 'Outer'
Inner1 =
Name = 'Outer.Inner'
Sub
Name = 'Outer.Inner.Sub'
Inner2
Name = 'Outer.Inner'
Sub
Name = 'Outer.Inner.Sub'
我确实认为可以通过子类化组件激活器并查找if classname=TName或if arguments.contains(TName)然后...
在这个例子中,我省略了让Names堆栈处理多个线程,实际上我没有使用名称,而是有一个接口堆栈,每个接口都知道他们的“父”是谁,但这表明了我试图实现的东西。
1条答案
按热度按时间fafcakar1#
示例的创建最终是在组件激活器中完成的。如果你为它创建一个装饰器,你就可以解决你的需求。
我将写下代码-您可以将其打包到自动完成所有工作的容器扩展中(查看
Spring.Container.*Extension
单元)。为了简洁起见,我将省略所有标准的创建和清理代码以及任何使此线程安全的代码。
调用
Build
后,运行以下代码:现在,每个通过反射创建对象的激活器(所以不是由委托创建的)都被修饰,并执行额外的推/弹出逻辑,您可以在
TName
委托中访问该逻辑。我声明TName如下:
及其注册:
下面是一个解析后的Touter示例的外观: