5

私は現在、共通の機能を共有する複数のかなり複雑なシステムの設計段階にあります(たとえば、両方に顧客関係管理(CRM)と販売機能があります)。したがって、ドメインの共通部分を抽出して、両方のアプリケーションで再利用しようとしています。

アプリケーションAとアプリケーションBがあり、どちらもCRM機能を使用しているとします。ほとんどの場合、CRMの機能は同じですが、どちらのアプリケーションもCRMに関連するいくつかの機能を強化することを好みます。

CRMシステムの基本バージョンを実装するライブラリを作成したいと思います。たとえば、顧客は次のように抽象化されます。

interface ICustomer {
  string CustomerNumber {get;set;}
}

ベースライブラリにはICustomerの基本的な実装があります

class Customer: ICustomer

アプリケーションAはこれを拡張できるようになりました。

interface IACustomer : ICustomer {
    bool ReceivesNewsletter {get;set;}
}

class ACustomer : Customer, IACustomer {
   ...
}

同様に、Bには独自のバリエーションがあります。

interface IBCustomer : ICustomer {
    string NickName {get;set;}
}

class BCustomer : Customer, IBCustomer {
    ....
}

抽象化の目的で、ベースライブラリで具象型をインスタンス化することはありませんが、ファクトリまたはDIコンテナを使用します。例:

interface ICrmFactory {
    ICustomer CreateCustomer();
}

AとBは、ACustomersまたはBCustomersがそれぞれ作成されるように、それに応じてファクトリを実装します。

これが私が意味するUML図です(アプリケーションBは表示されていません): アプリケーション設計

永続性のために、NHibernateを使用します。AとBはどちらも、追加のプロパティを含めるための独自のマッピング(コードによるマッピング)を提供します。さらに、AはIACustomerをACustomerのプロキシタイプとして定義し、BはIBCustomerをBCustomerのプロキシタイプとして定義します。

これで、NHibernateを使用して、AとBのエンティティ(たとえばA)を操作できます。

session.QueryOver<ACustomer>()
    .Where(c=>c.ReceivesNewsletter)
    .List()

ここで、ベースライブラリ(たとえば、ある種のサービスオブジェクト)の顧客と何かをしたいとします。非常に単純なバージョンのプロトタイプを作成しましたが、これまでのところ、これは正常に機能しているようです。

session.QueryOver<ICustomer>()
   .Where(c => c.CustomerNumber == "1234ABC")
   .List()

つまり、QueryOverで特定のエンティティのプロキシタイプの基本クラスを使用でき、NHibernateは正しいクエリを作成します(例:A)。

SELECT
    this_.Id as Id0_0_,
    this_.CustomerNumber as Customer2_0_0_,
    this_.ReceivesNewsletter as Receives3_0_0_ 
FROM
    ACustomer this_ 
WHERE
    this_.CustomerNumber = @p0;
@p0 = '1234ABC' [Type: String (4000)] 

私の質問

これらのクエリは常に期待どおりに機能しますか?基本ライブラリのクエリで、プロキシインターフェイスの基本タイプを常に安全に使用できますか?NHibernateは常に取得する「正しい」エンティティタイプとテーブルを見つけますか?または、これがクエリの効率に悪影響を与える状況がありますか?b / c NHibernateは推測作業を行う必要がありますか?このシナリオで知っておくべき他の落とし穴はありますか?

ドキュメントでこれに関する情報を見つけることができませんでした。このアプローチにより、一部のドメインの共通部分を独自のベースライブラリにきちんと移動できますが、確実に機能するようにしたいと思います。

4

1 に答える 1

1

このシナリオでは問題は見られません。特に、すべてのアプリケーションでICustomerへの実装は1つしかないためです。

アプリケーションごとに複数の実装があったとしても、IDによるロードで問題が発生する可能性があります(マッピングによっては、そのIDを持つ顧客が複数存在する可能性があるため、session.Load(42))。しかし、顧客のリストを受け取るためのクエリはまだ機能していました。

過去にNHibernateであなたと同様の問題を調べたとき、私はこの記事を読みました-インターフェースではなく派生基本クラスについて話しますが、それは同じ考えです:http: //codebetter.com/jameskovacs/2011/02/ 16 / getload-polymorphism-in-nhibernate-3 /

NHibernateは推測作業を行いません-初期化時に、特定のタイプに対して持つすべてのマッピングのストアを構築します。任意のタイプのクエリを作成すると、それを継承するマッピングされた正しいタイプが検出され、それに応じてクエリが実行されます。 。

于 2013-01-24T15:50:04.203 に答える