1

メソッドやコンパイラ ディレクティブ、またはビルド/コンパイルの実行時にクエリやデータベース接続などの特定のコンポーネントが active=false に設定されたり切断されたりすることを保証する方法はありますか? これらは他の何かによってオンになっていることが非常に多いようで、手遅れになるまで気付かない.

私の特定のインストールはDelphi 7です

4

3 に答える 3

5

GExpertsのSet Component Properties機能はそれを行うことができます。

于 2013-04-30T07:45:49.787 に答える
3

最良のオプションは、ストック接続コンポーネントをサブクラス化し、.Loadedそのような独自のオーバーライドメソッドで行うことだと思います

if not csDesigning in Self.ComponentState then
   if not Self.ActiveInDFM {new boolean published property} then
      if Self.Active then Self.Active := false;
inherited;

Delphi Form Designer の愚かさを (ab) 使用することで、新しいコンポーネントを IDE パレットに実際にインストールしなくても使用できます。ストック コンポーネント クラスと同じ名前を付けてから、独自のメソッドをフォームの interface-uses の最後に配置します。リスト:したがって、設計時にはストックコンポーネントがあり、コンパイル時にはそれが透過的に独自のものに置き換えられます。

または、(別のコンポーネントの場合) のようにフォーム宣言のすぐ上にサブクラス化することもできます。

type
   TPanel = class(ExtCtrls.TPanel)
   private
     ...

   TForm1 = class(TForm) ....

このアプローチは、IDE の制限を開発者に有利な方法で使用して、アスペクト指向プログラミングに類似していると見なされる可能性があると思います。


別のアプローチは、保存時またはビルド前に DFM の .Active プロパティを消去するスクリプトかもしれませんが、この方法は複雑です。

  • スタンドアロンのビルド サーバーとの統合は難しいかもしれません (異なる CI フレームワークごとに新しいスクリプトを試してみました)
  • Active設計時のプロパティもリセットされます。厳密な観点から、これは適切なことです。しかし、これはあまり便利ではないかもしれません。

Form と DataModule で同様のコードを使用することもできます.Loaded method(その場合、接続のメソッドの代わりにオーバーライドする必要があります)。

すべての Form の Loaded メソッドに同じコードをコピーして貼り付けることができます。

procedure TMyForm.Loaded; // override
var c: TComponent; i: integer;
begin
  try 
    for i := 0 to Self.ComponentsCount - 1 do begin
        c := Self.Components[i];
        if c is TCustomConnection then
           with TCustomConnection(c) do // Hate those redundant typecasts!
             if Connected then Connected := false;
        if c is TDataSet then
           with TDataSet(c) do // Delphi could took a lesson from Component Pascal
              if Active then Active := false;
        if c is ... // transactions, stored procedures, custom libriaries...
    end;
  finally
    inherited;
  end;
end;    

これはあまり狡猾な方法ではないように思われるため、最も信頼性が高くなります。それでも、コピー アンド ペーストの場合は大変です。後で新しいコンポーネントやライブラリを追加する場合は、すべてのフォームでコピー アンド ペーストされたコードを変更する必要があります。

このコードを一部の MyDBUtils ユニットでグローバル プロシージャに集中化することができますDisconnect(const owner: TComponent);

procedure TMyForm.Loaded; // override
var c: TComponent; i: integer;
begin
  try 
    MyDBUtils.Disconnect(Self);
  finally
    inherited;
  end;
end;

ただし、このアプローチには欠点もあります。

  • これにより、ユニットは、使用する可能性のあるすべてMyDBUtilsのデータベース関連のライブラリおよびコンポーネントと緊密に結合されます。さまざまなバイナリ モジュールで構成される大規模な継承プロジェクトの場合、歴史的にさまざまな db-access ライブラリに基づいており、移行の過程にあるため、すべてのアクセス ライブラリをすべてのバイナリ モジュールに取り込みます。
    1. これはアドホック DI フレームワークによって克服できますが、逆のことが起こる可能性があります。配信不足のリスクがあり、実際にそれを使用するか、それを使用するように変更されたプロジェクトにライブラリまたはコンポーネント ハンドラーを挿入するのを忘れる可能性があります。
  • 接続をリセットしてはならないコンポーネント (データセットとしてのオブジェクト配列、インメモリ テーブル、インメモリ NexusDB または SQLite データベースなど) がフォームに含まれる場合、アドホックで自明でない規則を考え出す必要があります。それらをオプトアウトします。
于 2013-04-30T06:17:56.537 に答える
1

私のアプリケーションでは、Tag設計時に接続のプロパティを 1 に設定しました。OnBeforeConnectイベントで をチェックしTag、1 に等しい場合は、接続を中止して 0 に設定します。

于 2013-04-30T10:15:00.263 に答える