8

私は、まったく新しいイントラネットプロジェクトのインフラストラクチャを作成し、ほぼすべてのベストプラクティスに従おうとしました。また、私も言及したいのですが、ゼロからアーキテクチャを作成するのはこれが初めてです。

現在、私のインフラストラクチャの最初のバージョンは準備ができており、正常に機能しています。しかし、次のバージョンで制限付きコンテキスト構造を実装したいと思います。

以下、現状を説明してみました。

DbCore:データ操作を担当します。EntityFramework5コードが最初に使用されました。DbContextクラスは1つだけで、すべてのDbSetが定義されています。また、GenericRepositoryパターンとUnit of Workパターンは、次のインターフェイスに基づいて実装されています。

IGenericRepository

public interface IGenericRepository<TEntity>
     where TEntity : class {
        void Delete(object id);
        void Delete(TEntity entityToDelete);
        System.Collections.Generic.IEnumerable<TEntity> Get(System.Linq.Expressions.Expression<Func<TEntity, bool>> filter = null, Func<System.Linq.IQueryable<TEntity>, System.Linq.IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "");
        System.Collections.Generic.IEnumerable<TEntity> GetAll();
        TEntity GetByID(object id);
        System.Collections.Generic.IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters);
        void Insert(TEntity entity);
        void Update(TEntity entityToUpdate);
    }

IUnitOfWork

 public interface IUnitOfWork {
        void Dispose();
        IGenericRepository<Test> TestRepository {
            get;
        }
        IGenericRepository<Log> LogRepository {
            get;
        }
        void Save();
    }

モデル: DbCoreおよびEntity Framework ドメインの責任ある格納エンティティモデル:ビジネスロジックレイヤーを表すと、Modelsプロジェクトに格納されたエンティティオブジェクトのDTOも格納されます。現在、次のインターフェイスIServiceを実装するServiceクラスに格納されているビジネスロジック

public interface IService<TEntity> {

        IEnumerable<TEntity> Get();
        TEntity GetByID(int id);
        void Insert(TEntity entity);
    }

このサービスクラスは、ctorパラメーターを介してUnitOfWorkを取得し、操作に使用します。また、エンティティオブジェクトをDTOに、またはその逆に変換するためにAutomapperが実装されました。今後、エンティティモデルに関心がなくなったすべての上位レイヤーは、DTOのみを使用します。したがって、ほぼすべてのプロジェクト(apiおよびwebを含む)がこのプロジェクトを参照します。

共通:ロギングなどの一般的に使用されるライブラリを保存する責任があります。

WebCore: APIやMVCなどのWebベースのプロジェクトで一般的に使用されるライブラリを保存する責任があります。また、MVCベースのプロジェクト用の拡張機能、ハンドラー、フィルターが含まれています。

Api: ASP.Net MVCWebAPIプロジェクトはサービスレイヤーを表します。ドメイン層を消費し、クライアントにサービスを提供します。コントローラーは、ctorパラメーターとしてIServiceインターフェースを取得し、それを使用してドメインレイヤーを介してデータレイヤーにアクセスします。

Web: ASP.Net MVC 4ベースのWebプロジェクトで、ユーザーとの対話を担当します。データにアクセスするためにApiメソッドを使用します。すべてのコントローラーは、HttpClientを介してAPIを接続するIConsumeRepositoryという名前のインターフェイスを取得します。

 public interface IConsumeRepository<TEntity> {
        Task<TEntity> Create(TEntity TestInfo);
        Task Delete(int id);       
        Task<IEnumerable<TEntity>> Get();
        Task<TEntity> Get(int id);
        TEntity New();       
        Task<TEntity> Update(TEntity TestInfo, int entityId);
    }

Autofacは、すべてのプロジェクトのIoCとDIを担当します。

今のところ、これは私の現在のインフラストラクチャです。評価する必要があるすべてを説明したと思います。

今、私は次のことを理解しようとしています、

質問1:私が使用した方法に影響を与えてはならないものはありますか?

質問2:境界コンテキストを実装するための最良のアプローチは何ですか?最近、Julie Lermanのビデオを見て、たくさんのサンプルプロジェクトをレビューしました。DbContextからBCを派生させるのを見た一般的なこと。しかし、私は確信が持てませんでした。BCはDbCore(データアクセス)層ではなくドメイン(ビジネスロジック)層にあるべきだと思っていたからです。

質問3:前述したように、私のApiプロジェクトとWebプロジェクトはDTOを使用しているため、両方ともドメインレイヤーを参照する必要があります。しかし、APIを使用してUIからビジネスレイヤーを分離し、エンティティ用にそれらを再度結合しているため、私はそれが好きではありませんでした。しかし、私はこれより良い方法を見つけることができませんでした。

これは長い質問になりましたが、より良いアーキテクチャを作成するためにあなたのアイデアを私と共有していただければ幸いです。

4

1 に答える 1

30

質問1:複雑なビジネスドメインと重要なビジネスロジックがあると仮定すると、ドメインレイヤーをインフラストラクチャの問題から分離する必要があるため、努力する価値があります。ただし、これは多くの場合そうではありません。ほとんどの場合、データをデータベースからUIに移動してから元に戻すだけの場合、これは過剰設計であり、可動部分が少ないものを探す必要があります。

質問2:(ユビキタス言語が異なる)異なるドメインモデルはいくつありますか?1?二?三?モデルごとに、他のモデルやインフラストラクチャの懸念から可能な限り分離します。

Eric Evansは、境界のあるコンテキストを主に言語の境界として定義しています(彼の本からの引用)。

BOUNDED CONTEXTは、特定のモデルの適用可能性を区切って、チームメンバーが、一貫している必要があるものと、それが他のCONTEXTとどのように関連しているかを明確かつ共有して理解できるようにします。そのコンテキスト内で、モデルを論理的に統一するように努めますが、それらの範囲外での適用性について心配する必要はありません。他のコンテキストでは、他のモデルが適用されますが、用語、概念と規則、およびユビキタス言語の方言が異なります。

DBContextは正しい方向を示しているかもしれませんが、それはインフラストラクチャの成果物であり、ドメインの概念ではないことを忘れないでください。これは、「作業単位とリポジトリのパターンの組み合わせを表し、データベースにクエリを実行して変更をグループ化し、変更を1つの単位としてストアに書き戻すことができます。」_(MSDNドキュメントから)。

DDDは、ドメインモデリングに関するものです。モデルを使用して、複雑なビジネスドメインの難しいビジネス上の問題を解決します。技術的な考慮事項からモデルの境界を導き出すことは、尻尾が犬を振っているような感じがすることがあります。モデルの境界を概念的に定義し、それに応じて技術インフラストラクチャを調整します。

質問3: DTOは、APIなどのコンテキスト境界を適用するための優れた方法です。APIは、他のモデルの破損防止レイヤーとして機能できます。人々が通常UIにそれらを使用する理由は、UIの概念をドメインモデルにブリードする必要をなくすためです。

完璧なアーキテクチャを求めないでください。また、「ベストプラクティス」は、実際には特定の状況に基づく単なるガイドラインであることを理解してください。あなたの状況は微妙に異なる可能性があることを理解した上で、他のより経験豊富な人々が提示したガイドラインに従ってください。摩擦を見つけたときに設計上の決定をリファクタリングすることを期待して、持っているものを使用してください。たとえば、後でUIへのDTOが過剰であることがわかった場合は、それらを削除します。可能な限り簡素化します。

于 2013-02-15T14:21:51.020 に答える