私はPOCプロジェクトを誰かに割り当て、コマンドクエリの分離、制御の反転(依存性注入を使用)、およびリポジトリパターンの両方を実装するように依頼しました。「誰か」が私にPOCソリューションプロジェクトをくれましたが、これがその方法であるかどうかはわかりません。ここでPOCプロジェクトについて簡単に説明します
- このプロジェクトは、プレゼンテーション層(PL)、ビジネスロジック層(BLL)、およびデータアクセス層(DAL)の単純な3層アプリケーションです。各層は個別のプロジェクトです
- プレゼンテーション層はWebアプリケーションであり、BLLとDALはクラスライブラリプロジェクトです。
- ビジネスレイヤーには、定義済みのリポジトリインターフェイスがあります。BLLライブラリの参照がDALプロジェクトに追加され、DALプロジェクト内には、リポジトリインターフェイスを実装する具象クラスがあります。これは、制御の反転が適用される方法です
- Command-Query-Separationが実行されるため、ビジネスレイヤーのリポジトリインターフェイスは、Add/UpdateメソッドとDeleteメソッドのみを宣言します。読み取りの場合、DALには直接「読み取り」インターフェースがあり、DALにはこれらのインターフェースを実装する具象クラスがあります。
- プレゼンテーション層には、BLLライブラリとDALライブラリの両方への参照が含まれています。追加/更新/削除の呼び出しは、BLLを介してDALにルーティングされますが、読み取りはDALから直接行われます。これは、読み取りを行うためにBLLをバイパスするというコマンドクエリ分離の概念に準拠していると思います。
これがすべてのセットアップ方法の図です。3つのプロジェクトがあります
- NW.Web
- NW.Business
- NW.DataAccess
以下は、さまざまなレイヤーのコードのスナップショットです。
--NW.Web-
// A class in the Presentation Layer
public class CustomerPage
{
// Business layer Interface from NW.Business namespace
private ICustomerBusiness ICustB;
//DAL Read interface from NW.DataAccess.Read namepsace
private ICustomerRead<Guid> ICustR;
//Constructor for the Customer Page that uses Constructor Injection
public CustomerPage(ICustomerBusiness ICustB, ICustomerRead<Guid> ICustR)
{
this.ICustB = ICustB;
this.ICustR = ICustR;
}
}
--NW.Business-
//Declaration of business interface in the Business Layer
interface ICustomerBusiness
{
void Persist();
}
// A class in the Business Layer that implements the business interface
public class Customer: ICustomerBusiness
{
//Repository interface object that will be injected by Constructor Injection.
private ICustomerRepository ICustRep;
public Customer(ICustomerRepository ICustRep)
{
this.ICustRep = ICustRep;
}
public void Persist()
{
ICustRep.AddOrUpdate();
}
}
//Declaration of Repository interface in the Business Layer
public interface ICustomerRepository
{
void AddOrUpdate();
void Delete();
}
--NW.DataAccess--
public class CustomerRepository : ICustomerRepository
{
public void AddOrUpdate()
{
//implementation of Add or Update
}
public void Delete()
{
//implementation of Delete
}
}
//A Read interface in the Data Access Layer
interface ICustomerRead<T>
{
// A read is returned as DTO since in Database this may map to more than 1 table
CustomerDTO GetCustomerDetails(T id);
}
// An implementation of the Read Interface in the Data Access Layer
namespace NW.DataAccess.Read
{
public class CustomerRead<T> : ICustomerRead<T>
{
public CustomerDTO GetCustomerDetails(T id)
{
//implementation here
}
}
}
私の直感は、ここに何か問題があるということです。CQRSまたは少なくとも上記の実装が一部の要件に対応していないようです
- Customer Businessオブジェクト(Customerクラス)は、内部目的(変数の初期化など)のためにデータベースから読み取る必要がある場合があります。読み取りがDAL層で直接定義されている場合、これを行う唯一の方法は、BLLでDALdllを参照することです。しかし、これは循環参照を作成し、行われるIOCに反します
- すべてのビジネスオブジェクトに共通の読み取り要件がある場合はどうなりますか?
助言がありますか ?