



Quite often new features are added into a code stream for demonstration purposes, or need to be hidden because they are not quite ready for release (especially true for monolithic EXEs), or the client cannot upgrade their database structures yet.

There usually are various home grown approaches to accomplish this ranging from command line parameters (beta switches to enable or disable functionality), to one off database metadata queries. These approaches can be unified in an interface added to your database “data session” as shown in the following code snippets.

type TFeatureSupportedPredicate = reference to function(DataSession :IDataSession): Boolean; TFeatureInfo = class (TObject) Supported :integer; FeatureSupportedPredicate :TFeatureSupportedPredicate; public constructor Create; end ; constructor TFeatureInfo.Create; begin inherited ; Supported := - 1 ; end type TDataSession = class ( TInterfacedObject ,IDataSession) var FFeatureSupportDictionary :TDictionary<string,TFeatureInfo>; constructor Create; override; end; constructor TDataSession.Create; begin //do some stuff FFeatureSupportDictionary := TDictionary<string,TFeatureInfo>.Create; end;

procedure TDataSession.AddFeatureSupportPredicate( const FeatureName : string ; Predicate :TFeatureSupportedPredicate); var FeatureInfo :TFeatureInfo; begin if FFeatureSupportDictionary.ContainsKey(FeatureName) then raise EFeatureSupportException. CreateFmt( 'A Feature Support Predicate is already '+ 'registered with the Name: ''%s'' ' ,[FeatureName]); FeatureInfo := TFeatureInfo.Create; FeatureInfo.FeatureSupportedPredicate := Predicate; FFeatureSupportDictionary.Add(FeatureName,FeatureInfo); end ; function TDataSession .IsFeatureSupported( const FeatureName : string ) :boolean; var FeatureInfo :TFeatureInfo; begin Result := False; if FFeatureSupportDictionary.TryGetValue(FeatureName,FeatureInfo) then begin if FeatureInfo.Supported = - 1 then FeatureInfo.Supported := ifthen(FeatureInfo.FeatureSupportedPredicate(Self), 1 , 0 ); Result := Boolean(FeatureInfo.Supported); end ; end ;





Now wherever you pass or inject your IDataSession interface, which in a Client/Server application is almost everywhere, you will have access to the FeatureSupport functionality, and you can add/test predicates with the following code snippets:

AddFeatureSupportPredicate(SomeFeature, function (DataSession: I DataSession): Boolean begin Result := DataSession.TableExists( ' SomeTableForTheFeature ' ); end ); if DataSession.IsFeatureSupported( SomeFeature ) then ....