私たちは、レガシー システムを .NET に移植する作業を進めています。これは、アーキテクチャをクリーンアップするためだけでなく、レガシー システムでは簡単に実現できない多くの新しい可能性を利用するためでもあります。
注: 投稿する前に投稿を読んでいると、所々で説明が少し速すぎた可能性があることに気付きました。詳細については説明しません。不明な点がある場合は、コメントを残してください(回答ではありません)。可能な限り補足します
レガシー システムはデータベースを使用し、100% カスタムで記述された SQL が随所に使用されています。データを必要とするコードはジョブに必要なもののみを取得するため、これによりテーブルが広くなります (つまり、列が多くなります)。
移植の一環として、カスタム SQL に加えて、使用できる ORM レイヤーを導入しました。私たちが選択した ORM は DevExpress XPO であり、この機能の 1 つがいくつかの問題を引き起こしました。つまり、たとえば Employee テーブルの ORM クラスを定義するときに、すべての列のプロパティを追加する必要があるということです。そうしないと、それらを取得できません。
これはまた、従業員を取得すると、少数の列しか必要としない場合でも、すべての列を取得することを意味します。
ORM を使用する利点の 1 つは、プロパティ関連のロジックを同じクラスに配置できることです。たとえば、姓、名、ミドルネームを組み合わせて「表示名」にする簡単な表現は、例としてそこに置くことができます。
ただし、どこかに SQL コードを記述した場合は、DAL のような構造で、またはどこでも、この式を複製する必要があります。これは間違っているように感じられ、バグとメンテナンスの悪夢のレシピのように見えます。
ただし、次の 2 つの選択肢があります。
- ORM、すべてをフェッチ、一度ロジックを記述可能
- SQL、必要なものを取得、ロジックを複製する必要がある
次に、代替案を考え出しました。ORM オブジェクトは辞書からコード生成されるため、一連のダム クラスも生成することにしました。これらは同じ数のプロパティを持ちますが、同じ方法で ORM に関連付けられません。さらに、生成されたすべてのオブジェクトにインターフェースを追加し、ORM オブジェクトとダム オブジェクトの両方にこのインターフェースを実装させました。
これにより、このロジックの一部をインターフェイスに関連付けられた拡張メソッドに移動することができました。ダム オブジェクトは、SQL クラスにプラグインするのに十分な情報を持っているため、DataTable を取得する代わりに、利用可能なロジックを使用して List を取得できるため、これは機能しているように見えます。
ただし、これにより別の問題が発生しました。従業員が誰であるか (つまり、システム内の識別子) と名前 (ファースト、ミドル、ラスト) を知る必要があるコンテキストでのみ従業員を表示または処理するコードを書きたい場合、私はこのダム オブジェクトを使用します。私を呼び出すコードが実際にこれらすべてのものを提供していることをコンパイラが保証することはありません。
1 つの解決策は、どのプロパティに値が割り当てられているかをオブジェクトに認識させることです。割り当てられていないプロパティを読み取ろうとすると、例外が発生してクラッシュします。これにより、コードが十分な情報を渡していない場合に、実行時に契約違反を検出する機会が得られます。
これも私たちには不格好に見えます。
だから基本的に私がアドバイスしたいのは、他の誰かがこの状況にあったか、そうであるか、そしてあなたが与えることができるヒントやアドバイスです.
現時点では、テーブルを分割することはできません。レガシ アプリケーションは、ポートのサイズのために何年も存在する必要があり、.NET コードは 3 年以内にリリースされるタイプのプロジェクトではありませんが、途中のリリースで段階的に導入されます。そのため、レガシー システムと .NET コードの両方が同じテーブルを操作する必要があります。
また、これが理想的な解決策ではないことも承知していますので、「このようにするべきではなかった」などのアドバイスはご遠慮ください。私たちはこれをよく知っています:)
私たちが調査したことの 1 つは、"コントラクト" を使用して XML ファイルなどを作成することです。したがって、この XML ファイルに次のようなものを入れることができます。
- これらの 50 個のプロパティを持つ Employee クラスがあります
- さらに、プログラムのさまざまな部分に、これらの 7 つのバリエーションがあります。
- さらに、これらの 10 個のロジックがあり、それぞれがプロパティ X、Y、および Z を必要とします (X、Y、および Z はこれらの 10 の間で異なります)。
これにより、これらの 8 つのクラス (完全なクラス + 7 つの小さなバリエーション) をコード生成し、バリエーション #3 にプロパティ X、Y、および K が存在することをジェネレーターに検出させることができます。ロジックまたはロジックが必要とするインターフェースをこのクラスに自動的に追加します。これにより、さまざまな程度のプロパティ カバレッジを持つさまざまなタイプの従業員クラスを作成し、このクラスでサポートされるすべてのロジックをジェネレーターに自動的に追加させることができます。
私のコードは、タイプ IEmployeeWithAddressAndPhoneNumbers の従業員が必要であると言うことができます。
これもダサく見える。