Coo*_*lio 6 delphi linker inversion-of-control
我在delphi中创建了一个IoC,能够自动注册任何具有IocSingletonAttribute的类.
AutoRegister如下所示.
procedure TIocContainer.AutoRegister;
var
ctx: TRttiContext;
rType: TRttiType;
attr: TCustomAttribute;
&Type: PTypeInfo;
begin
ctx := TRttiContext.Create;
for rType in ctx.GetTypes do
Begin
for attr in rType.GetAttributes do
Begin
if TypeInfo(IocSingletonAttribute) = attr.ClassInfo then
Begin
&Type := IocSingletonAttribute(attr).&Type;
RegisterType(&Type, rType.Handle, True);
End;
End;
End;
end;
Run Code Online (Sandbox Code Playgroud)
然后我创建一个实现并将IocSingletonAttribute添加到它.看起来像这样
[IocSingleton(TypeInfo(IIocSingleton))]
TIocSingleton = class(TInterfacedObject, IIocSingleton)
procedure DoSomeWork;
end;
Run Code Online (Sandbox Code Playgroud)
所以,现在到程序的实际代码.如果我写下面的代码,IoC不起作用.AutoRegister过程没有选择TIocSingleton.
var
Ioc: TIocContainer;
Singleton: IIocSingleton;
begin
Ioc := TIocContainer.Create;
try
Ioc.AutoRegister;
Singleton := Ioc.Resolve<IIocSingleton>();
Singleton.DoSomeWork;
finally
Ioc.Free;
end;
end.
Run Code Online (Sandbox Code Playgroud)
但是,如果我编写下面的代码,一切都按预期工作.请注意我是如何声明TIocSingleton类并使用它的.
var
Ioc: TIocContainer;
Singleton: IIocSingleton;
ASingleton: TIocSingleton;
begin
Ioc := TIocContainer.Create;
ASingleton := TIocSingleton.Create;
try
Ioc.AutoRegister;
Singleton := Ioc.Resolve<IIocSingleton>();
Singleton.DoSomeWork;
finally
Singleton.Free;
Ioc.Free;
end;
end.
Run Code Online (Sandbox Code Playgroud)
基于此,我假设Delphi的编译器链接器在第一个示例中删除了TIocSingleton,因为它从未在应用程序的任何部分中明确使用.所以我的问题是,是否可以为某个类转换编译器的"删除未使用的代码"功能?或者,如果我的问题不是链接器,任何人都可以阐明为什么第二个例子有效而不是第一个?
感谢 Sebastian Z 的回答和 Agustin Ortu 的评论。他们的回答让我找到了最终的解决方案。不幸的是,不可能仅对一个类使用 STRONGLINKTYPES,并且需要以某种方式引用该类。我决定不使用奥古斯汀·奥尔图的精确建议,但我确实使用了这个概念。
在定义 IoC 的单元中,我输出以下空过程。
procedure IocReference(AClass: TClass);
implementation
procedure IocReference(AClass: TClass);
begin
end;
Run Code Online (Sandbox Code Playgroud)
在创建 IoC 使用的类的类中,我添加以下内容
initialization
IocReference(TIocSingleton);
end.
Run Code Online (Sandbox Code Playgroud)
使用过程来阻止链接器删除代码而不是仅仅调用类函数(例如(TIocSingleton.ClassName))的原因是它提供了更好的信息。如果另一个程序员阅读了代码,他们可以很好地猜测为什么该行在那里。
| 归档时间: |
|
| 查看次数: |
266 次 |
| 最近记录: |