10

私はエンティティフレームワークを使用してDALを実装しています。アプリケーションでは、3つのレイヤー(DAL、ビジネスレイヤー、プレゼンテーション)があります。これはウェブアプリです。 DALの実装を開始したとき、DALはビジネス・レイヤー上のサービスによって与えられたObjectContextをメソッドが受け取って操作するクラスをDalに持たせるべきだと考えました。この決定の背後にある論理的根拠は、異なるObjectContextが異なるDB状態を参照するため、外部キーの一致やその他の不一致の問題により一部の操作が拒否される可能性があるということです。DTO + UnitOfWorkパターンは、WebアプリケーションのDALを設計するための良いアプローチですか?

サービス・レイヤーからオブジェクト・コンテキストを生成して伝播すると、レイヤー間の結合が高くなることに気付きました。そこでAutomapperによってマッピングされたDTOを使用することにしました。(管理されていないエンティティや、高結合を主張するセルフトラッキングエンティティ、エンティティを上位レイヤに露出させる、低効率)、UnitOfWorkを使用することにしました。したがって、ここに私の質問があります:

  1. これは、WebアプリケーションのDALを設計する正しい方法ですか?どうして?
  2. 「はい」と答えた場合、どのようにUnitOfWorkパターンでDTOのコンセプトを調整するのですか?
  3. "いいえ"と答えた場合、これはWebアプリケーションのDALを設計する正しい方法でしょうか?

可能な場合は、回答をサポートする参考文献を記載してください。現在の設計について

:プレゼンテーション、ビジネス、DAL:

アプリケーションは三つの層の上に開発することが計画されています。ビジネスレイヤにはファサードとサービスの両方があります

サービスでのみ表示されるITransaction(変更を破棄して保存する2つの方法のみ)というインターフェイスがあります。トランザクションを管理するために、ObjectContextとITransactionを拡張するTransactionクラスがあります。ビジネスレイヤーでは、他のObjectContextメソッドにアクセスできないようにすることを念頭に置いて設計しました。

DALでは、2つの汎用タイプ(エンティティ用と関連DTO用)を使用して抽象リポジトリを作成しました。このリポジトリには、一般的な方法で実装されたCRUDメソッドと、汎用リポジトリのDTOとエンティティをAutoMapperでマップする2つの汎用メソッドがあります。抽象リポジトリコンストラクタは引数としてITransactionをとり、ITransactionをProctected ObjectContextプロパティに割り当てるために、ObjectContextを要求します。

具体的なリポジトリは、.netタイプとDTOだけを受け取り、返すべきです。

作成する一般的な方法は、添付されたエンティティの一時的なIDまたは永続的なIDを生成しません(SaveChanges()を使用してから、必要なトランザクション性を失うまで)。これは、サービスメソッドがそれを使用してBLのDTOを関連付けることができないことを意味します)

答えて

7

ここでは多くのことが行われています...私は3層アーキテクチャを使用していると仮定します。それは、私があなたが作ったいくつかの意思決定と、それらを作る背後にある動機が何であるかは不明です。一般的には、あなたのクラスでObjectContextを渡すべきではないと言います。接続管理を扱うマネージャやリポジトリクラスが必要です。これにより、DB状態管理の問題が解決されます。リポジトリのパターンがここでうまく機能していることがわかります。そこから、接続管理が1か所で処理されるため、作業単位パターンを簡単に実装できるはずです。私があなたのアーキテクチャについて知っていることを考えれば、あなたはPOCO戦略を使用すべきだと言います。 POCOを使用しても、あなたをORMプロバイダに密接に結びつけることはありません。利点は、POCOがObjectContextと(おそらく何らかのリポジトリを介して)やりとりすることができることで、これは変更の追跡を可視化することになります。これからも、作業単位(トランザクション)パターンを実装して、ビジネストランザクションの動作方法を完全に制御できるようになります。私はこれがどのように一緒に収まるかを説明するための非常に有用な記事であることがわかります。コードはバグですが、記述するアーキテクチャのタイプのベストプラクティスを正確に示しています。Repository, Specification and Unit of Work Implementation

質問番号1に対する私の答えの短いバージョンは「いいえ」です。上記のリンクは私があなたにとってよりよいアプローチであると信じているものを提供します。

+0

質問の最新バージョンをご覧ください...ありがとう! – JPCF

+0

優れたリンク...! – JPCF

2

dependency injectionと対照の逆転が一般的に意味するものを見てください。それはObjectContextのライフサイクルを「外部から」制御する能力を提供するでしょう。すべてのhttp要求に対してオブジェクトコンテキストのインスタンスが1つしか使用されないようにすることができます。依存関係を手動で管理しないようにするには、StructureMapをコンテナとして使用することをお勧めします。

もう1つの有用な(ただし、非常にトリッキーで難しい)手法は、永続性の抽象です。直接ObjectContextを使用する代わりに、Repositoryという名前を使用して、データストア用のAPIのようなコレクションを提供する必要があります。これは有用なseamを提供します。これは、基礎となるデータ格納メカニズムを切り替えたり、テストのために永続性を完全に取り除いたりするために使用できます。

すでにJasonが提案しているように、POCO`s(プレーンな古いclrオブジェクト)も使用する必要があります。それでもエンティティフレームワークとの暗黙的な結合が存在するにもかかわらず、生成されたクラスを使用するよりもはるかに優れていることに注意してください。あなたは十分に速く他の場所で見つけることができませんかもしれません

もの:

  1. unit of workの使用を避けるようにしてください。モデルでトランザクション境界を定義する必要があります。
  2. generic repositoriesの使用を避けるようにしてください(IQueryableについても注意してください)。
  3. repository pattern nameであなたのコードをスパムすることは必須ではありません。

また、domain driven designについての読書を楽しむこともできます。複雑なビジネスロジックに対処するのに役立ち、コードを手続き的でなくオブジェクト指向にするための大きなガイドラインを示します。

+0

質問の最後のバージョンを見てください...ありがとう! – JPCF

+0

EFでDDDの例がありますか?私は特にトランザクション境界をどのように定義するのか興味があります。 –

+0

@Ladislav残念ながら、私はEFにあまり慣れていません。 NHibernateが依然として優れていることを盲目的に信じています。リポジトリ部分だけが変更されます。トランザクション境界は、有効な状態の原因であり、アトミック操作で保持されているため、それ自体が集約ルートによって描画されます。それらのモデルを正しくモデリングすることが重要です。 –

1

私はあなたの現在の問題に焦点を当てます:正に、私はあなたのObjectContextを渡すべきではないと思います。私はそれが問題につながると思う。コントローラまたはビジネスサービスがObjectContext/ITransactionをリポジトリに渡すと仮定しています。 ObjectContextが適切にダウンストリームで処理されるようにする方法を教えてください。ネストされたトランザクションを使用するとどうなりますか?トランザクションがダウンストリームの場合、ロールバックを管理するのは何ですか?

あなたの最善の策は、あなたのアーキテクチャーでトランザクションをどのように管理するかについて、いくつかの定義を加えることにあります。 TransactionContopeをコントローラ/サービスで使用することは、ObjectContextがそれを尊重して以来、良いスタートです。もちろん、コントローラ/サービスがトランザクションを持っている他のコントローラ/サービスを呼び出すかもしれないことを考慮する必要があるかもしれません。ビジネストランザクションとそれ以降のデータベース呼び出しを完全に制御するシナリオを可能にするには、トランザクションを管理し、スタックの上下にトランザクションを管理する何らかの種類のTransactionManagerクラスを作成する必要があります。私は、NCommonがトランザクションの抽象化と管理の両方で異常な仕事をしていることを発見しました。 UnitOfWorkScopeクラスとTransactionManagerクラスを見てください。リポジトリにUnitOfWorkを使用させるNCommonのアプローチには同意しませんが、必要に応じて簡単にリファクタリングすることができます。

は限り、あなたのpersistantIDの問題が行くように、check this out

+0

すべての前に、ありがとう!あなたはとても興味があるようです。サービスでトランザクションを作成しますが、ITransactionを使用します。このインターフェイスはDisposeとSaveChancesの2つのメソッドのみを公開します。 TransactionオブジェクトはObjectContextですが、DALで扱われます。サービスはITransactionのみを参照します。トランザクションを保存して廃棄することは、サービスメソッドでのプログラマの責任です。ネストされたトランザクションは実装されておらず、単純なので、ロールバックは考慮しません。 – JPCF

4

は、私はいつもコードはプログラマのための世界よりもより良いものを説明することができると信じていました。これは特にこのトピックで当てはまります。それで、私は、あなたが期待しているすべての魔法使いの中の素晴らしいサンプルアプリケーションを見てみることをお勧めします。

alt text

プロジェクトがSharp Architectureと呼ばれ、それがMVCNHibernateを中心とされていますが、あなたがそれらを必要なときだけEFものでNHibernate部品を交換すると同じアプローチを使用することができます。このプロジェクトの目的は、Webアプリケーションを構築するためのコミュニティのベストプラクティスをすべてアプリケーションテンプレートに提供することです。

それはすべての一般的なカバーし、ここなどIoCコンテナ、のDTOの使用、

との依存関係を管理し、トランザクションを管理し、ORMのを使用している場合も珍しく話題のほとんどはsample applicationです。

私はこれを読んで、これを試してみると、それは私のためのようなあなたのための本当の宝物になるでしょう。

関連する問題