0

階層化された .NET 4.0 アプリケーションを作成しています。データ レイヤーは Entity Framework を使用して実装され、エンティティ インスタンスを呼び出し元、つまりビジネス レイヤーに提供するリポジトリがあります。エンティティ フレームワークが特定のエンティティを 2 回 (キーなどで) 要求されると、同じインスタンスが返されるため、エンティティに加えた変更は、エンティティが使用されている他の場所に反映されます。ただし、有効期限ポリシーがないため、実際にはキャッシュ機能ではありません。少なくとも多くの場合、エンティティ フレームワークは引き続きデータベースにクエリを実行するため、パフォーマンスはあまり改善されないようです。ポイントは、各エンティティのインスタンスが (コンテキストごとに) 1 つだけであることを確認することです。

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

編集開始

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

また、すべてのビジネス オブジェクト クラスに実装する必要のないソリューションを探しています。何百もの可能性があります。リポジトリを実装する人にとって可能な限り透過的な、フレームワーク コードでのソリューションを希望します。エンティティ フレームワーク自体も特定のエンティティ タイプを認識しませんが、エンティティ フレームワークはエンティティ モデル開発者に対して透過的なこの機能を提供できます。

編集終了

私の質問は次のとおりです。

  • この「オブジェクトごとに 1 つのインスタンスのみ」という動作の名前はありますか? Google の検索語句は何でしょうか。
  • リファレンス、ガイドライン、またはベスト プラクティスはありますか、それともこの問題を扱う設計パターンはありますか?
  • そのような機能を作成するのに役立つ、またはそれを完全に提供する.NETのクラスはありますか?

ありがとう、ピーター。

4

2 に答える 2

0

これがあなたに方向性を与えることができるサンプルです。クラスUser(プライベートIDセッター付き)があるとします。

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になります。したがって、新しいユーザーまたは既存のユーザーを定義できます。
  • リフレクションは、プライベートプロパティ値を設定するために使用されます
  • シングルトンの実装と次のIDの生成は単純です(簡単な例として)

今、あなたはすることができます:

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

そして、どこか別の場所で、同じユーザーインスタンスを取得できます。

var otherRepository = UserRepository.Instance;
User user = otherRepository.FindById(1);
于 2012-05-03T10:37:25.690 に答える
0

はい、名前があります。これはIdentity Mapパターンと呼ばれ、通常はオブジェクト キーとオブジェクトのペアの単なる辞書です。

于 2012-05-03T10:13:41.270 に答える