Creating a Delphi IoC. How to disable Delphi's linker from removing unused classes

[亡魂溺海] 提交于 2021-02-16 16:23:06

问题


I've created a IoC in delphi with the ability to automatically register any classes that have a IocSingletonAttribute to it.

The AutoRegister looks like the following.

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;

I then create a implementation and add the IocSingletonAttribute to it. It looks like this

[IocSingleton(TypeInfo(IIocSingleton))]
TIocSingleton = class(TInterfacedObject, IIocSingleton)
  procedure DoSomeWork;
end;

So, now to the actual code of the program. If I write the code below the IoC doesn't work. The AutoRegister procedure didn't pick up TIocSingleton.

var
  Ioc: TIocContainer;  
  Singleton: IIocSingleton;  
begin  
  Ioc := TIocContainer.Create;
  try    
    Ioc.AutoRegister;
    Singleton := Ioc.Resolve<IIocSingleton>();
    Singleton.DoSomeWork;
  finally 
    Ioc.Free;
  end;
end.

But if I write the code below instead everything works as expected. Notice how i have declared TIocSingleton class and have used it.

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.

So based on this, I'm assuming Delphi's compiler linker is removing TIocSingleton in the first example because it was never explicitly used in any part of the application. So my question is, is it possible to turn of the compiler's 'remove unused code' feature for a certain class ? Or if my problem isn't the linker, can anyone shed light on why the second example works but not the first ?


回答1:


Add the {$STRONGLINKTYPES ON} directive to the .dpr. Then those types should be included. But it will definitely blow up your application, as it is not available for a single class.




回答2:


Thanks to Sebastian Z answer for and for Agustin Ortu comment. Both their responses got me to a final solution. It's not possible to use STRONGLINKTYPES for just one class, unfortunately, and the class needs to be referenced somehow. I decided not to use Augstin Ortu exact suggestion but I did use the concept.

In the unit where IoC is defined I output the following empty procedure.

procedure IocReference(AClass: TClass);

implementation

procedure IocReference(AClass: TClass);
begin
end; 

And in the class that creates a class to be used by IoC I add the following

initialization
  IocReference(TIocSingleton);
end.

The reason to use a procedure to keep the linker from removing the code instead of just calling a class function, eg (TIocSingleton.ClassName) is that it provided better information. If another programmer reads the code they can take a good guess as to why that line is there.



来源:https://stackoverflow.com/questions/42054460/creating-a-delphi-ioc-how-to-disable-delphis-linker-from-removing-unused-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!