3

これは、より設計上の問題です。

私はアプリを構築しており、次のようにリポジトリパターン構造を作成しました:

私のコア名前空間は、DAL/Repository/BusinessLogic レイヤー アセンブリです。

ところで、私はデータ接続として Dapper.NET マイクロ ORM を使用しています。そのため、私の SqlConnection オブジェクトに拡張機能が表示されます。

データ アクセスのために、ベース リポジトリ クラスを作成しました。

namespace Core
{
    public class BaseRepository<T>: IDisposable where T : BaseEntity 
    {
        protected SqlConnection conn = null;


        #region Constructors
        public BaseRepository() : this("LOCAL")
        {

        }

        public BaseRepository(string configurationKey = "LOCAL")
        {
            conn = new SqlConnection(ConfigurationManager.ConnectionStrings[configurationKey].ConnectionString);
        }
        #endregion

        #region IDisposable
        public void Dispose()
        {
            conn.Dispose();
        }
        #endregion


        /// <summary>
        /// returns a list of entities
        /// </summary>
        /// <typeparam name="T">BaseEntity type</typeparam>
        /// <param name="sproc">optional parameters, stored procedure name.</param>
        /// <returns>BaseEntity</returns>
        protected virtual IEnumerable<T> GetListEntity(string sproc = null)
        {
            string storedProcName = string.Empty;
            if (sproc == null)
            {
                storedProcName = "[dbo].sp_GetList_" + typeof(T).ToString().Replace("Core.",string.Empty);
            }
            else
            {
                storedProcName = sproc;
            }

            IEnumerable<T> items = new List<T>();
            try
            {
                conn.Open();
                items = conn.Query<T>(storedProcName,
                                                     commandType: CommandType.StoredProcedure);
                conn.Close();
            }
            finally
            {
                conn.Close();
            }


            return items;
        }


    }
}

そして、私が持っているエンティティごとに、ExtendedUser、Messages と言って、次のような Interface-Class ペアを作成しています。

namespace Core
{
    public class ExtendedUserRepository : BaseRepository<UsersExtended>,IExtendedUserRepository
    {

        public ExtendedUserRepository() : this("PROD") 
        {
        }

        public ExtendedUserRepository(string configurationKey) : base(configurationKey)
        {
        }


        public UsersExtended GetExtendedUser(string username)
        {
            var list = GetListEntity().SingleOrDefault(u => u.Username == username);
            return list;
        }

        public UsersExtended GetExtendedUser(Guid userid)
        {
            throw new NotImplementedException();
        }


        public List<UsersExtended> GetListExtendedUser()
        {
            throw new NotImplementedException();
        }
    }
}

上記のコードは、エンティティ :ExtendedUser の 1 つにすぎません。

問題は、私が持っているエンティティごとに Interface-ClassThatImplementetsInterface ペアを作成する必要があるかどうかです。それとも、すべてのエンティティからのすべてのメソッドに対して、1 つの RepositoryClass と 1 つの IRepository インターフェイスのみを使用する必要がありますか?

4

2 に答える 2

1

理由もなくインターフェイスを作成する必要はないと思います。ここでベースリポジトリクラスが必要な理由さえわかりません。これはリポジトリではなくDAL(Data Access Layer)だと思いますが、これは定義の主張です。

適切な DAL 実装では、データベース構造をビジネス ロジック構造から分離する必要があると思いますが、sp_GetList_XXXEntityNameXXX パターンをハードコーディングしたり、DAL の外部でストアド プロシージャ名を渡したりしても分離されません。

すべてのエンティティ リストが 1 つの方法で取得され、ビジネス ロジックでパラメータなしでエンティティの完全なセットが常に必要になると考える場合は、非常に楽観的であるか、アプリケーションが非常に単純です。

実装からインターフェイスを分離する必要があるのは、異なる実装を置き換える/ラップアウトする場合、または 1 つのクラスにいくつかのインターフェイスを混在させる場合のみです。それ以外の場合は必要ありません。

リポジトリを作成するときは、エンティティの観点から考えないでください。リポジトリにはビジネス ロジックが含まれており、使用シナリオに基づいて構築する必要があります。あなたが持っているようなクラスを持つことは、データ アクセス レイヤーに関するものです。DAL は、ビジネス ロジックで必要なクエリに基づいて構築されます。おそらく、一度にすべてのユーザーのリストが必要になることはありませんが、アクティブなユーザー、特権ユーザーなどのリストが必要になることがよくあります.

どのようなクエリが必要になるかを予測するのは非常に難しいため、ビジネス ロジックから設計を開始し、DAL メソッドを追加することを好みます。

于 2012-08-31T19:42:43.197 に答える
1

複雑なドメイン モデルを持つシステムは、データベース アクセス コードの詳細からドメイン オブジェクトを分離する、Data Mapper (165) によって提供されるレイヤーなどのレイヤーの恩恵を受けることがよくあります。このようなシステムでは、クエリ構築コードが集中しているマッピング層の上に別の抽象化層を構築する価値があります。

http://martinfowler.com/eaaCatalog/repository.html

汎用リポジトリを使用するとfindBy(array('id' => 1))findOneBy(array('email' => 'john@bar.com'))findById()findAll()などの一般的なメソッドを使用できます。実際、インターフェースは 1 つです。

これを達成するために、リポジトリによって管理されるドメイン オブジェクトを示す具体的な実装を常に作成する必要があります。getUsersRepository().findAll()

さらに、より複雑なクエリが必要な場合は、具体的な実装で新しいメソッドを作成し、findMostActiveUsers()それをアプリケーション全体で再利用できます。

さて、あなたの質問に答えます:

アプリケーションは、少なくとも 1 つのインターフェース (一般的なメソッドを持つ一般的なインターフェース) を期待します。しかし、上で述べたような特定のメソッドを持つことができれば、別のインターフェース (RepositoryInterface や UsersRepositoryInterface など) を使用したほうがよいでしょう。

それを念頭に置いて、リポジトリ インターフェイスのみに依存します。クエリの構築は、具体的な実装によってカプセル化されます。したがって、アプリケーションの残りの部分に影響を与えることなく、リポジトリの実装を (たとえば、本格的な ORM を使用して) 変更することができます。

于 2012-08-31T21:54:40.217 に答える