2011-11-09 5 views
1

私はDDDを使用してWCFサービスを設計しています。 ドメインオブジェクトを作成するためにリポジトリを呼び出すドメインサービスレイヤがあります。リポジトリは、ORMではなくADO.Netを使用して実装されています。データはStored Procsを使用してDBから得られます。オブジェクトを作成している間は、SPは状態のIDを返します。 SPはアドレステーブルと状態テーブルを結合しません。状態は、id、abbr、およびnameプロパティを持つ値オブジェクトクラスStateによって表されます。状態オブジェクトのリストは、アプリケーションが非揮発性データであるため起動するときに(system.runtime.caching.memorycacheを使用して)キャッシュできます。一般的に私はテーブルからすべてのそのようなルックアップデータを取得できるLookupDataRepositoryを持っています。これで、AddressRepositoryはstateのIDからアドレスのStateプロパティを設定する必要があります。
擬似コード:DDDアプリケーションのデータベースからのルックアップデータのキャッシュを実装するレイヤーはどれですか?

class AddressRepository : IAddressRepository 
{ 
    Address GetAddressById(int id) 
    { 
     // call sp and map from data reader 
     Address addr = new Address(id); 
     addr.Line = rdr.GetString(1); 
     addr.State = // what to do ?, ideally LookupCache.GetState(rdr.GetInt32(2)) 
    } 
} 

class State 
{ 
    public int Id; 
    public string Abbr; 
    public string Name; 
    enum StateId {VIC, NSW, WA, SA}; 
    public static State Victoria = // what to do, ideally LookupCache.GetState(StateId.VIC) 
} 

// then somewhere in address domain model 
if(currentState = State.Victroia) 
{ 
    // specific logic for Victoria 
} 

私の質問は、このキャッシュを置くためにどの層であります?。サービス、リポジトリ、すべてのレイヤにわたって利用可能な別個のアセンブリ

答えて

8

キャッシュはどこに配置しますか?場合によります。 あなたがシナリオなら、あなたは結果がなります(私はあなたがドメインサービスのemを呼ぶと信じて)いくつかのアプリケーションサービスにあなたのIAddressRepositoryを注入することを次のようになります。リポジトリレベルで

  • キャッシングは(すべてのサービスが利益になることになります長所)。
  • リポジトリレベルでキャッシュすると、すべてのサービスでキャッシュ(cons)を使用する必要があります。
  • サービスレベルでのキャッシュは、その特定のサービスとメソッドを使用するクライアント/サービスに対してのみキャッシュされます(長所/短所)
  • サービス管理でトランザクション管理を行っている場合は、リポジトリレベルでのキャッシュ読み取り操作がキャッシュにヒットすることがあり、書き込み操作を実行しようとしている読み取りデータが変更されていないことをトランザクションが検証できないことがあります。

私はサービス層でキャッシュすることになります。より自然な感じがして、キャッシュする場所とタイミングをより詳細に制御できます。リポジトリレベルは、通常、低粒度です。サービスレイヤーとそのメソッドは、ユースケースに近づき、キャッシュする時期と対象を知っています。

私は本当にSystem.Runtime.Caching.MemoryCache.Defaultへの静的な参照を保持

public class CacheManager : ICacheManager 
{ 
public Address Address 
     { 
      get { } 
      set { } 
     } 
} 

のようなキャッシュラッパーを書くことをお勧めします。

キャッシングタイプが安全になり、キャストはラッパー内でのみ行われます。 Mocked ICacheManagerを注入してサービスをユニットテストすることもできます。

より高度なアプローチは、アスペクト指向プログラミングとデコレータ/インターセプタでこれを行うことです。あなたはStackOverFlowでたくさんの良い情報を持っていますhttps://stackoverflow.com/search?q=AOP+caching

+0

私は同じ行について考えていました。私が違った唯一のことは、これらの値オブジェクトを読み取る新しいリポジトリ(技術的にはリポジトリではなく、より多くのデータアクセスオブジェクト)を作成することです。キャッシュは、これらの値オブジェクトの特定のサービス層にあります。実際のドメインリポジトリは、ドメインオブジェクトの作成時にもこのサービスを使用します。 – softveda

+0

あなたは答えが好きなら、答えを確認してください。それは私を助けますが、それは他の人がこの質問を見つけるのを助け、確かな答えを持っています。 –

関連する問題