I have many objects registered in Spring4d container,some as Singleton.When Application shutdown almost Singletons correct call own Destroy,but some no and FastMM reports Memory leaks. I'm looking for a way,how Log which objects have problem. I try experienced with Container Extension with this simple example:
unit Spring.Container.HCV.Extension;
interface
uses
Spring.Container.Extensions, Spring.Container.Core, Spring.Container.Builder;
type
THCVLoggerBuilderInspector = class(TInspectorBase)
protected
procedure DoProcessModel(const kernel: IKernel; const model: TComponentModel); override;
end;
TFakeBuilderInspector = class(TInspectorBase)
protected
procedure DoProcessModel(const kernel: IKernel; const model: TComponentModel);
override;
end;
THCVLoggerExtension = class(TContainerExtension)
protected
procedure Initialize; override;
end;
implementation
uses
Spring.Container.Common;
procedure THCVLoggerBuilderInspector.DoProcessModel(const kernel: IKernel;
const model: TComponentModel);
var
lLT:string;
begin
if model.ComponentType.IsInstance then
begin
case model.LifetimeType of
TLifetimeType.Unknown: lLT:='Unknown ';
TLifetimeType.Singleton: lLT:='Singleton ';
TLifetimeType.Transient: lLT:='Transient ';
TLifetimeType.PerResolve: lLT:='PerResolve ';
TLifetimeType.SingletonPerThread: lLT:='SingletonPerThread';
TLifetimeType.Pooled: lLT:='Pooled ';
TLifetimeType.Custom: lLT:='Custom ';
else
end;
kernel.Logger.Info('Builder: [%s] %s',[lLT,model.ComponentTypeName]);
end;
end;
procedure THCVLoggerExtension.Initialize;
begin
Kernel.Builder.AddInspector(THCVLoggerBuilderInspector.Create);
Kernel.Builder.AddInspector(TFakeBuilderInspector.Create);
end;
procedure TFakeBuilderInspector.DoProcessModel(const kernel: IKernel; const
model: TComponentModel);
begin
kernel.Logger.Info('FakeBuilderInspector');
end;
end.
In Registration I have
container.AddExtension<THCVLoggerExtension>;
Container correct call THCVLoggerExtension.Initialize
but in my inspectors is never called DoProcessModel
.Why?
Possibly because you added the extension after you called Build
on the container? Another reason could be simply not seeing any logging - did you place a breakpoint in the DoProcessModel
to verify it's not called?
To the actual problem: Memory leaks with singletons are almost always a result of the container not figuring out the correct refcounting of those classes. Pass the correct TRefCounting
value to AsSingleton
when registering any classes that are not inherited from TInterfacedObject
.