Creation of Delphi IoC. How to disable the Delphi linker from deleting unused classes

I created IoC in delphi with the ability to automatically register any classes that have an IocSingletonAttribute.

The auto registry is as follows.

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; 

Then I create an implementation and add IocSingletonAttribute to it. Looks like this

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

So, now to the actual program code. If I write the code below, IoC does not work. AutoRegister procedure did not 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, everything will work as expected. Notice how I declared the TIocSingleton class and 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. 

Therefore, based on this, I assume that the Delphi compiler linker removes the TIocSingleton in the first example, because it was never used explicitly in any part of the application. So my question is: is it possible to enable the "delete unused code" compiler function for a particular class? Or if my problem is not the linker, can someone shed some light on why the second example works, but not the first?

+6
source share
2 answers

Thanks to Sebastian Z for the comment and for the comment of Agustin Horta. Both of their answers led me to a final decision. Unfortunately, you cannot use STRONGLINKTYPES for only one class, and the class must somehow be referenced. I decided not to use the exact Augstin Ortu proposal, but I used the concept.

In the block where the IoC is defined, I issue the following empty procedure.

 procedure IocReference(AClass: TClass); implementation procedure IocReference(AClass: TClass); begin end; 

And in the class that creates the class that IoC will use, I add the following

 initialization IocReference(TIocSingleton); end. 

The reason for using a procedure that allows the linker to remove code instead of just calling a class function, for example (TIocSingleton.ClassName), is because it provided better information. If another programmer is reading the code, he might think about why this line exists.

+1
source

Add the {$STRONGLINKTYPES ON} directive to .dpr. Then these types should be included. But this will definitely hurt your application as it is not available for one class.

+3
source

Source: https://habr.com/ru/post/1014716/


All Articles