0

これが私の質問です。それから私はあなたにそれらの背景を与えます:

  • アプリケーションの設計として方法2を使用したいので、ビジネス以外のコードへの参照を導入したり、コアプロジェクトのデータベースモデルへのアクセスを許可したりせずに、方法1のようなフィルタリングを提供する方法はありますか?

  • コードの再利用をどのように処理しますか?各オブジェクトの名前空間はProject.Core.DomainやProject.Core.Servicesのようなものですが、奇妙に感じる場合は、そのプロジェクトに保存されていないときに名前空間をCompanyName.Core.Domainのようなものにします。現在、これを処理するためにソースコードファイルをコピーし、名前空間の名前を変更していますが、これを処理するための組織的な方法や、私が考えていなかった何かがあるかどうか疑問に思っています。

私が使用しているテクノロジー:

  • ASP.NET MVC 3
  • Linq-to-SQL
  • StructureMap
  • Moq
  • MSTest

方法1:


Webプロジェクトのセットアップに使用した方法は次のとおりです。 ここに画像の説明を入力してください

データプロジェクトには、すべてのリポジトリとLinqデータコンテキストが含まれます。リポジトリでは、IQueryableを使用してデータベースからオブジェクトのコレクションを返します。

public IQueryable<Document> List()
{
    return from d in db.Documents
           select d;
}

これにより、静的メソッドであるフィルターをセットアップすることができました。これらもデータプロジェクトに保存されました。

public static IQueryable<Document> SortByFCDN(this IQueryable<Document> query)
{
    return from d in query
           orderby d.ID
           select d;
}

サービスレイヤーでは、このようにフィルターを適用できます。

public IPagedList<Document> ListByFCDN(int page, IConfiguration configuration)
{
    return repository.List().SortByFCDN().ToPagedList(page, configuration.PageSize, configuration.ShowRange);
}

したがって、リポジトリは、すべてのアイテムをIQueryableオブジェクトとして返すListAllメソッドを提供するだけでよく、サービスレイヤーは、データのサブセットを返す前に、それをフィルターで除外する方法を決定します。

私はこのアプローチが好きで、サービスにコードの大部分を残しながら、リポジトリをよりクリーンにしました。

方法2


現在、Webプロジェクトを設定する方法は次のとおりです。 ここに画像の説明を入力してください

オニオンアーキテクチャの使用:

  • コア:ビジネスドメインモデル、アプリケーションのすべてのインターフェイス、およびサービスクラスの実装が含まれています。
  • インフラストラクチャ:リポジトリの実装、Linqデータコンテキスト、およびLinqデータベースモデルをビジネスモデルにマップするためのマッピングクラスが含まれています。

ビジネスコードをデータベースコードから分離しているので、IQueryableにアクセスするために、コアプロジェクトでLinqなどに参照を追加したくありません。そのため、リポジトリレイヤーでフィルタリングを実行し、データベースモデルをドメインモデルにマップしてから、ドメインオブジェクトのコレクションをサービスレイヤーに返す必要がありました。これにより、リポジトリにメソッドが追加される可能性があります。

4

1 に答える 1

0

これは私がやったことです:

1)コアプロジェクトにフィルタリング列挙オブジェクトを作成しました。

public enum FilterType
{
    SortFCDN
}

2)サービスクラス(これもコアプロジェクト内)で、次のようにします。

    public IPagedList<Document> ListByFCDN(int page)
    {
        Dictionary<FilterType, object> filters = new Dictionary<FilterType, object>();

        filters.Add(FilterType.SortFCDN, "");

        return repository.List(page, filters);
    }

3)リポジトリ内(インフラストラクチャプロジェクトの下):

    public IPagedList<Document> List(int page, Dictionary<FilterType, object> filters)
    {
        //Query all documents and map to the model.
        return (from d in db.DbDocuments
                select d).Filter(filters).Map(
                    page, 
                    configuration.Setting("DefaultPageSize", true).ToInt(), 
                    configuration.Setting("DefaultShowRange", true).ToInt());
    }

4)インフラストラクチャプロジェクトにフィルタクラスを作成します。

public static class DocumentFilters
{
    public static IQueryable<DbDocument> Filter(this IQueryable<DbDocument> source, Dictionary<FilterType, object> filters)
    {
        foreach (KeyValuePair<FilterType, object> item in filters)
        {
            switch (item.Key)
            {
                case FilterType.SortFCDN:
                    source = source.SortFCDN();
                    break;
            }
        }

        return source;
    }

    public static IQueryable<DbDocument> SortFCDN(this IQueryable<DbDocument> source)
    {
        return from d in source
               orderby d.ID
               select d;
    }
}

次に、サービスレイヤー(コアプロジェクト)は、適用するフィルターを決定し、クエリが実行される前にそれらのフィルターをリポジトリ(インフラストラクチャプロジェクト)に渡すことができます。FilterTypeごとに1つだけが適用される限り、複数のフィルターを適用できます。

フィルタディクショナリは、フィルタのタイプと、フィルタに渡す必要のある値/オブジェクトを保持できます。新しいフィルターも簡単に追加できます。

于 2011-07-19T17:45:39.083 に答える