2

データベースに格納されている一部のデータにアクセスするWCFサービスを設計しています。

DBへの実際のアクセスは、いくつかのORMレイヤー(現在はNHibernateですが、これは実装の詳細です)によって処理されます。

この種のシナリオの適切な設計は何ですか?

素朴なアプローチは次のようになります。

public class ServiceImplementation : IService
{
     // NHibernate session
     private ISession session;

     // service methods that use *session*
}

これは特にNHibernateに結合され、サービスクラスに初期化の管理とORMロジックコードの所有を強制します。

私の質問は特に:

  • サービスがDB/ORMレイヤーから分離されている分離設計を実現するにはどうすればよいですか?
  • いつがdb access / ORMレイヤーを初期化する必要がありますか?サービスはそれを管理していますか?

これは非常に一般的なシナリオであるため、いくつかの「パターン」/ベストプラクティスが存在すると思います。

オンラインで入手できるほとんどの例は、これを実現する方法(ORMを使用してDBにアクセスする方法など)を示していますが、設計の観点から、より大規模にこれを適切に行う方法は示していません。

4

1 に答える 1

1

1 回だけ初期化したい場合は、次の属性を使用してサービス実装クラスを設定することを検討してください。

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]

これにより、サービスは単一のインスタンスをメモリに保持し、複数の呼び出し元がすべてそのインスタンスにアクセスします。欠点は、コードをスレッドセーフにする必要があることです。さらに、2 番目の WCF サービスを呼び出すことはできません (これには、再入可能同時実行が必要です)。

ただし、このシナリオでは、DB/ORM 側を制御するクラス インスタンスをサービス内に保持して、必要な分離を実現できます。

DB/ORM の初期化は、サービスのコンストラクターで実行できます。

DB/ORM 機能を含む静的メンバー変数を使用するのは賢明ではないことに注意してください。これは、静的な値でさえ、十分な非アクティブ期間が与えられると、サービス ホストによって回収される可能性があるためです。

もちろん、これは目的を達成するための 1 つの方法にすぎません。複数の初期化のコストと、スレッド セーフなコードを記述する PIA を比較することでメリットが得られる場合があります。妥協点は InstanceContextMode.PerSession を使用することです。これにより、単一のユーザー セッションで ORM が 1 回だけ初期化され、ユーザーが複数の呼び出しを行う可能性が高い場合に初期化が削減されます。セッションの定義と制御のオーバーヘッドはせいぜい些細な刺激であり、私がどれだけ長い間とりとめをしてきたかを考えると、この応答の範囲外です。

于 2013-03-07T18:01:32.323 に答える