学習目的でASP.NET Web Api 2ソリューションを構築していますが、問題が発生しました。私が行方不明になっていることを正確に誰かに教えてもらえないかと思っていました。
私のWeb APIソリューションには4つのレイヤーがあります。
参照は次のとおりです。データ<リポジトリ>ドメイン
Webは、DIの3つのレイヤーすべてを参照します。
個別のドメインレイヤーの背後にある考え方は、データレイヤーまたはリポジトリレイヤーで発生することにはまったく気づかないということです。リポジトリ層のIRepositoryと、その結果として取得したいビジネスモデルを提供することで、要件の概要を示します。ドメイン層の要求を満たすのは、リポジトリ層次第です。
ここに私の難問があります:
このパターン/レイヤーアプローチを機能させるために重要な部分が欠けているように感じます。
私はごまかすことで簡単に続行できることを知っています(つまり、コンテキストのようなデータ固有のものへのサービスアクセスを提供します)。しかし、私はそれを適切な方法で行う方法を学ぶことにもっと興味があります。
これまでに行った調査では、大きく異なる結果が得られました。
何が欠けていますか?
私のコードについてさらに説明するために編集してください:
Github上のMy Generic Repositoryには、次のようなCRUDメソッドが含まれています。
public abstract class RepositoryBase<TData, TDomain, TId> : IRepository<TDomain, TId> where TDomain : EntityBase<TId>, new() where TData : class, IDataEntity<TId>, new()
{
private readonly ShortStuffContext _context;
public RepositoryBase(ShortStuffContext context)
{
_context = context;
}
public IEnumerable<TDomain> GetAll()
{
return _context.Set<TData>().BuildQuery<TData, TDomain>();
}
}
BuildQueryは、すべてのエンティティを取得するか、式を取得して単一のエンティティをフェッチし、ValueInjecterを使用してデータモデルをドメインモデルにマッピングするLINQ拡張機能です。
リポジトリメソッドは、インターフェースを介してドメインレイヤーによって要求されます。
public interface IRepository<TDomain, TId> where TDomain : EntityBase<TId>
{
IEnumerable<TDomain> GetAll();
}
RepositoryBaseは、現在空になっている個々のPOCOのリポジトリによって拡張され、TData、TDomain、およびTIdのみをリポジトリベースに提供します。
public class UserRepository : RepositoryBase<Data.Entities.User, User, decimal>
{
public UserRepository(ShortStuffContext context)
: base(context)
{
}
}
これは、コンストラクターインジェクションを介してドメインレイヤーから要求できますIRepository<User, decimal> UserRepository
ninject InRequestScope
バインディングを介して。
アプリケーションの大きさはどれくらいですか?これを考えすぎている可能性は十分にあります。アプリケーションが大規模なエンタープライズグレードのアプリケーションでない限り、推奨している高度な疎結合はおそらく不要です。
このレベルの疎結合が依然として必要であると判断した場合は、「サービス」オブジェクトを返すサービス層を作成します。これは、MVCのモデルの表示と同様の機能を果たします。次に、ドメインモデルからサービスモデルにオブジェクトをマップするコードをサービスレイヤーに記述します。
Data RepositoryがCRUDオブジェクトを返している間に、サービスレイヤーがアクションの結果を返す必要があるという事実が原因である可能性があることに注意してください 例えば:
public InvoiceView GetInvoice(int invoiceID);
ドメイン内のいくつかの異なるテーブル/オブジェクトから、名前、住所、ラインアイテムなど、公開したいあらゆるデータを含むInvoiceView
オブジェクトを返します。
public class InvoiceView
{
public int InvoiceID;
public Address ShippingAddress;
public Address BillingAddress;
public List<LineItem> LineItems;
...
}
同様に、単純にアクションを実行し、アクションの結果を示すオブジェクトを返すService Layerメソッドがあります。
public TransactionResult Transfer(
int sourceAccountID, int targetAccountID, Money amount, ValidationToken token);
重要:データから完全に分離することはできません。たとえオブジェクトIDまたはUUIDであっても、コンシューマーは常にデータについてある程度の知識を持っている必要があります。