Mega Code Archive

 
Categories / Delphi / Examples
 

A real singleton class implementation (Part II)

Title: A real singleton class implementation (Part II) Question: How to implement a real singleton class that can have only one instance. Answer: See my previous ID 2311 for the first method. With this second method singleton is totally protected :) Exemple below change the application exception to debug handler. Interface IDebug give access to object specified and created in implementation at startup and deactivate by default. Thanks to Peter Morris (mailto:pete@stuckindoors.com) for the idea ! // ************************************************************************** // * Implementation of a real Delphi singleton object * // * by using interface * // ************************************************************************** unit U_Singleton; interface uses SysUtils; type IDebug = interface(IUnknown) function GetInstance : IDebug; function IsActive : boolean; procedure SetActive(Value : boolean); procedure ShowException(Sender: TObject; E : Exception); end; function GetDebug : IDebug; implementation uses Dialogs, Forms, Classes; type TDebug = class(TObject, IDebug) private FOldHandler : TExceptionEvent; FActive : boolean; private function QueryInterface(const IID: TGUID; out Obj): Integer; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; protected procedure HandleException(Sender: TObject; E: Exception); virtual; public constructor Create; destructor Destroy; override; function GetInstance : IDebug; function IsActive : boolean; procedure SetActive(Value : boolean); procedure ShowException(Sender: TObject; E : Exception); end; var Debug : IDebug; //------------------------------------------ function GetDebug : IDebug; begin result := Debug; end; //------------------------------------------ constructor TDebug.Create; begin // Do what to do end; //------------------------------------------ destructor TDebug.Destroy; begin // Do what to do SetActive(false); inherited; end; //------------------------------------------ function TDebug.GetInstance; begin result := self; end; //------------------------------------------ function TDebug.QueryInterface(const IID: TGUID; out Obj): Integer; stdcall; begin end; //------------------------------------------ function TDebug._AddRef: Integer; stdcall; begin end; //------------------------------------------ function TDebug._Release: Integer; stdcall; begin end; //------------------------------------------ procedure TDebug.HandleException(Sender: TObject; E: Exception); begin Showexception(Sender, E); end; //------------------------------------------ function TDebug.IsActive : boolean; begin result := FActive; end; //------------------------------------------ procedure TDebug.SetActive(Value : boolean); begin if (FActive = Value) then Exit; case (Value) of True : begin FOldHandler := Application.OnException; Application.OnException := HandleException; end; False : Application.OnException := FOldHandler; end; FActive := Value; end; //------------------------------------------ procedure TDebug.ShowException(Sender: TObject; E : Exception); var s : string; begin if Assigned(Sender) then s := 'Except send by ' + Sender.ClassName + ' : '; MessageDlg(s + E.Message, mtError, [mbOK], 0); end; //------------------------------------------ initialization try Debug := TDebug.Create; except on E : Exception do MessageDlg(E.Message, mtError, [mbOK], 0); end; finalization // Let's cleaning process by Windows... end.