2012-02-22 8 views
4

私は自分のUIに「接続」したいビジネスオブジェクトを持っています。私は、オブジェクトをデータに対応させるための部分的なソリューションをいくつか見てきましたが、それらはすべて抽象レイヤーを追加するなど、ビジネスオブジェクトに大きな変更を加えました。RTTIを使用してオブジェクトを意識したコントロールを作成するためにプロパティ書き込みメソッドをプログラムで変更することはできますか?

私は、Delphiの新しいバージョンで改善されたRTTIを検討しています。非常に面白くて便利です。私はそれをプログラムですべてのプロパティの新しい書き込みメソッドを挿入するために使用できるかどうか疑問に思っています。

この方法は、フォームの作成時にTEditの子孫がオブジェクトプロパティへの参照を渡すことで動作します。 TEditは、そのプロパティの属性に自身への参照を挿入します(もちろん、デストラクタまたは別の参照が与えられている場合は削除されます)。 TEditは、プロパティの書き込みメソッドが、元の書き込みメソッドを呼び出した後にTEditに変更を通知するものに置き換えられることも保証します。

これは実現可能ですか?大きなショーストッパーは、新しい書き込みメソッドを注入することは不可能なので、この質問のタイトルです。

派生プロパティにも潜在的な問題がありますが、その解決策を見つけることは可能であるはずです。

+0

おそらくhttp://docwiki.embarcadero.com/CodeSamples/en/TVirtualMethodInterceptor_(Delphi)とhttp://blog.barrkel.com/2010/09/virtual-method-interception.htmlは始める場所ですか? – ComputerSaysNo

+1

ビンディングのような音! TEditの子孫の最小限のプロトタイプを提供できますか? – menjaraz

+0

'control'認識のビジネスオブジェクトや'ビジネスオブジェクト '認識コントロール(VCLのc.fデータ認識コントロール)が本当に必要なのは何ですか?私の意見では、ビジネスオブジェクトはUIコントロールを知らなくてはなりません。 – menjaraz

答えて

0

このpostと題してとなります。偉大な分割を誘導しますCobus Krugerはビジネスオブジェクトについて話しました。

彼は調理ソリューションが要件と基本的に準拠しています。

  1. は、最近のDelphiのバージョンで導入された高度なRTT​​I機能をご利用ください。
  2. プレゼンテーションロジックからビジネスロジックを分離します。

任意のPODO(Plain Old Delphi Object)がビジネスオブジェクトとして機能します。

魔法は、任意のビジネス・オブジェクトに任意ののTWinControlを結びつけるTObjectBindingクラスに産みます。

抜粋:

TObjectBinding = class 
private 
    fCtx: TRttiContext; 
    fControlType: TRttiType; 
    fObjType: TRttiType; 

    fPropFieldMapping: TDictionary<TRttiProperty, TRttiField>; // Dictionary of object Properties & corresponding Fields 

    fControl: TWinControl; // The control (normally form) 
    fObj: TObject; // Object it represents. 

    procedure CreateMappings; 

    function FindField(Prop: TRttiProperty; out Field: TRttiField): Boolean; 
    function FieldClass(Field: TRttiField): TClass; 

    // Modify these to change the rules about what should be matched. 
    function IsValidField(Field: TRttiField): Boolean; 
    function IsValidProp(Prop: TRttiProperty): Boolean; 

    // Modify these to change the mappings of property type to VCL control class. 
    procedure AssignField(Prop: TRttiProperty; Field: TRttiField); 
    procedure AssignProp(Prop: TRttiProperty; Field: TRttiField); 

    // Used from AssignField/AssignProp. Extend these to support a wider range of properties. 
    function GetPropText(Prop: TRttiProperty): string; 
    procedure SetPropText(Prop: TRttiProperty; const Text: string); 
public 
    constructor Create(Control: TWinControl; Obj: TObject); 
    destructor Destroy; override; 
    // 
    procedure Load; 
    procedure Save; 
end; 

私はこれがあなたのために良い出発点となることを願っています。

1

私はちょうど私がこのアプローチする方法を追加しますので、あなたの質問はすでにプログラミングのスキルを進め、私のあなたを置く:私はおそらくのためのTListを開始したいというような何かを書き込もうとしたら

をTBusinessObjectの各フィールド。このリストは、変更をプッシュする必要があるときに更新が必要なものを示すために使用されます。

したがって、TEditを作成すると、TBusinessObjectのデータに関連付けられたリストに自身が追加されます。 TBusinessObjectがそのデータを更新すると、接続オブジェクトのリストを介して実行されます。 TEditが表示され、それがTEditであったことを知ると、.Textを更新するコードを実行します。私がTCaptionを添付すると、コードは.Captionを更新します。

TEditは、指定したとおり、値が更新されたときにTBusinessObjectに指示する必要があります。私はこれが難しい点だと思います。新しいTEditを作成してTListを追加して、変更があったときに通知する必要がある人を維持することができます。 .Tagを使用してTBusinessObjectのフィールド番号を指定すると、OnChange(または何らかのイベント)がTBusinessObject.FieldUpdate [TEdit.Tag、NewValue]のようなものを呼び出し、ビジネスロジックをトリガーすることができます。これにより、TBusinessObjectは他のフィールドを更新することになります。フィールドには、自分自身のTListsを更新するフィールドがある可能性があります。

環状更新を防止するには、イベントをトリガーせずにコントロールを更新する方法が必要です。私が書いた1つのプログラムでは、コントロールを更新する2つのメソッド、SetValueとChangeValueがありました。 SetValueは任意のイベント(OnChange、OnValidate)を無効にし、コントロールの値を更新してイベントを再度有効にしました。 ChangeValueは単に値を変更し、必要に応じてコントロールのイベントのいずれかを発生させました。

これを行うには、おそらくスリッキーな方法がありますが、うまくいけば、これは思考のための食糧を与えます。

+0

これは実行可能なソリューションのように思えますが、上記のアイデアの目的は、オブジェクトが完全に認識できないものを作成することでした。実行時にバインドに必要なすべてをオブジェクトに挿入します。 – boileau

1

オブジェクト認識コントロールを作成するためにRTTIを使用してプロパティ書き込みメソッドをプログラムで変更することはできますか?

いいえ、不可能です。 RTTIは情報を提供しますが、実行時に型を変更することはできません。

大きなショーストッパーが新しいwriteメソッドを注入すると、のようなものがあるはずあなたは、実行時にこれを変更するためには、この質問

ためので、タイトルは不可能であるということでしょうあなたが設定できるイベントハンドラです。これは簡単な概念ですが、呼び出し時間(通常は直接呼び出しで十分である間接処理)と必要なメモリ(それぞれのプロパティにはTEventスタイルフィールドが余分に必要です)の両方でランタイムオーバーヘッドがあります。これはのためにあなたが必要ならばを実装するのは簡単ですが、コンパイラが "万一の場合"のすべてのクラスに対してこのようなコードを自動的に生成してしまうと危険です。

実行時にメモリ内のコードをどうにか修正することを考えているのであれば、それはうまくいかず、最高では信頼できません。

+0

+1:確かに、コードを注入するとセキュリティ上の問題が発生する可能性があります。 – menjaraz

関連する問題