2012-05-03 12 views
0

レイヤード.NET 4.0アプリケーションを作成します。データレイヤーは、Entity Frameworkを使用して実装され、エンティティインスタンスを呼び出し元、つまりビジネスレイヤーに提供するリポジトリがあります。エンティティフレームワークが特定のエンティティを2回(例えばキーによって)尋ねられると、それは同じインスタンスを返すので、エンティティに対して行った変更は、そのエンティティが使用される他の場所に反映される。期限切れポリシーがないため、実際にはキャッシュ機能ではなく、少なくとも多くの場合、エンティティ・フレームワークが依然としてデータベースにクエリを行うため、パフォーマンスはあまり改善されないようです。要は、各エンティティのインスタンス(コンテキストごとに)が1つだけであることを確認することです。Entity Frameworkのように "オブジェクトごとに1つのインスタンス"を実現する

ビジネスレイヤーでは、エンティティは、エンティティと構造が異なる可能性のあるビジネスオブジェクトにマップされます。この場合も、データレイヤのリポジトリと同様に、ビジネスオブジェクトのインスタンスを取得するための集中アクセスポイントがあります。私の目標は、エンティティ・フレームワークが提供する機能と同じ機能を持つことです。つまり、ビジネス・レイヤー内の「特定のオブジェクトに対して常に同じインスタンスを戻す」という意味です。私は、アプリケーション内の特定のビジネスオブジェクトへのアクセスがすべて同じインスタンスで機能することを確認したいと思います。

開始入力

コンテキスト認識が重要です!エンティティ・フレームワークと同様に、各ビジネス・オブジェクト・インスタンスの一意性は、厳密にはアプリケーション全体ではなく、コンテキスト・ベースごとに提供される必要があります。ビジネス層にはコンテキストの概念もあり、各コンテキストには各ビジネスオブジェクトの独自のインスタンスが必要です。このインスタンスは、コンテキストが使用されているすべての場所で再利用する必要があります。

また、単一のビジネスオブジェクトクラスごとに実装する必要がないソリューションを探しています。潜在的に何百もあります。私は、リポジトリを実装している人にできるだけ透明なフレームワークコードのソリューションを好むでしょう。エンティティフレームワーク自体も特定のエンティティタイプについて知らないが、エンティティフレームワークはエンティティモデル開発者にこの機能を透過的に提供することができる。

のEND EDIT

私の質問は以下のとおりです。

  • 名がこの "唯一のインスタンスオブジェクトごとに" 行動のためにありますか? Google検索用語は何ですか?
  • 参考資料、ガイドライン、またはベストプラクティス、またはこの問題を扱うデザインパターンがありますか?
  • .NETには、このような機能を記述するのに役立つクラスがありますか、それとも完全に提供するのでしょうか?

ありがとうございました、 Peter。

答えて

0

はい、名前があります。これはIdentity Mapパターンと呼ばれ、一般的にオブジェクトキーとオブジェクトのペアの辞書に過ぎません。

+0

偉大な、ヒントありがとう!ビジネスレイヤーで再利用できる(可能な限り)ジェネリック実装を知っていますか、それとも私自身で書く必要がありますか? – Peter

0

ここにあなたに方向を与えることができるサンプルです。あなたは(プライベート同上セッター付き)クラスのユーザーを持って考えてみましょう:

public class User 
{ 
    public int Id { get; private set; } 
    public string Name { get; set; } 
} 

ストアリポジトリ内のすべてのユーザー(私は迅速なアクセスのための辞書を使用):

public class UserRepository 
{ 
    private static UserRepository _instance = new UserRepository(); 
    Dictionary<int, User> _users = new Dictionary<int, User>(); 

    private UserRepository() 
    { 
    } 

    public static UserRepository Instance 
    { 
     get { return _instance; } 
    } 

    public IEnumerable<User> FindAll() 
    { 
     return _users.Values; 
    } 

    public User FindById(int id) 
    { 
     return _users[id]; 
    } 

    public void SaveOrUpdate(User user) 
    { 
     if (user.Id == 0) 
     { 
      int nextId = _users.Count + 1; 
      PropertyInfo id = typeof(User).GetProperty("Id"); 
      id.SetValue(user, nextId, null); 
      _users.Add(user.Id, user); 
      return; 
     } 

     _users[user.Id] = user; 
    } 
} 

ここで興味深いのは何:

  • リポジトリはシングルトンです。 1つだけのコレクション/辞書のユーザーが存在する必要があるため
  • プログラム内でユーザーを作成すると、IDは0になります。したがって、新しいユーザーまたは既存のユーザーを定義できます
  • 反射が使用されます

    UserRepository repository = UserRepository.Instance; 
    repository.SaveOrUpdate(new User() { Name = "Joe" }); 
    

    そして、どこか別のY:今、あなたが行うことができます

  • シングルトンの実装と次のIDの生成が(ちょうど簡単な例のために)簡単です

をプライベートプロパティ値を設定しますユーザーの同じインスタンスを取得することができます:

var otherRepository = UserRepository.Instance; 
User user = otherRepository.FindById(1); 
+0

ありがとうございます。しかし、あなたのアプローチには私のシナリオには2つの欠点があります。私がそれを十分に明確にしなかった場合、謝罪します。文脈認識の欠如とリポジトリ開発者への透明性の欠如。私はそれに応じて私の質問を洗練した。おそらく私はあまりにも多く(特に第2部分)を求めていると思いますが、私が想像していることはできませんが、あなたがそれについてもっと考えているなら、私はそれらを読むことができます! – Peter

+0

@Peterあなたのエンティティの辞書を持つ単純なクラス 'Context'はどうですか? Btwでは、すべてのクラスのリポジトリを実装する必要はありません。 'リポジトリ'のような汎用リポジトリを作成し、任意のパラメータに使用することができます: 'Repository '。 –

+0

実際に私は既にContextクラスを持っており、ビジネスオブジェクトを格納することは私の心を越えています。しかし、私は単にあなたの一般的なアプローチを使用することはできません。私のビジネスオブジェクトリポジトリには特定のロジックが必要であり、(共通の汎用インターフェイスを共有していても)1つずつ書き込まなければなりません。そこで重要なのは、私のリポジトリに、各リポジトリでできるだけ小さなフットプリント(理想的にはゼロ)で、コンテキストにあるインスタンスキャッシュを使用させるにはどうしたらいいですか? – Peter

関連する問題