4

私の最初の実際の (テストではない) NHibernate/Castle.ActiveRecord プロジェクトは急速に発展しています。私は NHibernate/Castle.ActiveRecord を約 1 か月使用していますが、まだ WindowsForms アプリケーションでセッションを処理する方法がわかりません。

一般的な取り扱い方法は、私にはうまくいきません。

  • SessionPerRequest、SessionPerConversation などはすべて WebApplications などでのみ機能します。
  • 私が正しい場合、SessionPerApplicationは推奨されません/非常に危険です
  • SessionPerThread は、WindowsForms スレッドという 1 つのスレッドしかないか、ボタンをクリックするたびに新しいスレッドを作成するため、あまり役に立ちません。最初のことは、アプリケーションがメモリを使いすぎて、古いオブジェクトをメモリに保持することです。ech ボタン クリック用のワーカー スレッドを使用すると、ロードされたオブジェクトがスレッドよりも長く存続するため、遅延読み込みを無効にします。
  • SessionPerPresenter も機能していません。フォームで「サブプレゼンター」を開いて、ユーザーが参照オブジェクト (外部キー) を検索/ロード/選択できるようにすることが一般的であるため、プレゼンターが破棄される - どういう意味ですか?セッションは閉じられましたが、参照プロパティ (外部キー) を埋めるために「スーパープレゼンター」で使用されたオブジェクトです。

私は Google と bing を何時間も使用し、多くのことを読みましたが、私のケースに関する良い Web サイトを 1 つだけ見つけました: http://msdn.microsoft.com/en-us/magazine/ee819139.aspx。そこでは SessionPerPresenter が使用されますが、「サブプレゼンター」には、オブジェクト全体ではなく ID のみが与えられます! そして、この例には外部キーがなく、オブジェクトが「スーパープレゼンター」に返されるシナリオがないことがわかります。

質問

  1. windowsforms/desktop-application のセッション処理の他の方法はありますか?
  2. すべてのプレゼンターにセッション プロパティまたはセッション コンストラクター パラメーターを追加できますが、UI コード全体でセッション処理を行うのは適切ではないと感じています。
  3. 例外が発生すると、NHibernate は私にセッションを強制終了させたいと思っています。しかし、それが「のみ」のビジネスロジック例外であり、NHibernate-Exception ではない場合はどうなりますか?

私の問題のほとんどをカバーする例を作ろうとしています。

// The persisten classes
public class Box
{
  public virtual int BoxId{get;set;}
  public virtual Product Content{get;set;}
  ...
}

public class User
{
  public virtual int UserId{get;set;}
  public virtual IList<Product> AssigenedProducts{get;set;}
  ...
}

public clas Product
{
  public virtual int ProductId{get;set;}
  public virtual string PrductCode{get;set;}
}

.

// The presenter-classes
public class ProductSearchPresenter : SearchPresenter<Product> { ... }
public class ProductEditPresenter : EditPresenter<Product> { ... }
public class UserSearchPresenter : SearchPresenter<User> { ... }
public class UserEditPresenter : EditPresenter<User> { ... }
public class BoxSearchPresenter : SearchPresenter<Box> { ... }
public class BoxEditPresenter : EditPresenter<Box> { ... }
// The search-presenters allow the user to perform as search with criterias on the class defined as generic argument and to select one of the results
// The edit-presenters allow to edit a new or loaded (and given as parameter) object of the class defined as generic argument

現在、次のユースケースがあります。これらはすべて、同じアプリケーションで同時に非同期で実行できます (使用は、プレゼンター間で切り替えるだけです)。

  1. BoxSearchPresenter のインスタンスを使用してオブジェクトを検索および選択する
    1. このユースケースの一部は、ProductSearchPresenter のインスタンスを使用して BoxSearchPresenter の基準を満たすことです。
    2. このユースケースの一部は、BoxEditPresenter のインスタンスを使用して、BoxSearchPresenter-instance の選択されたオブジェクトを編集および保存することです。
  2. UserSearchPresenter のインスタンスを使用してオブジェクトを検索および選択する
    1. このユースケースの一部は、UserEditPresenter のインスタンスを使用して、UserSearchPresenter の選択されたオブジェクトを編集および保存することです。
    2. このユースケースの一部は、ProductSearchPresenter を使用して、User.AssignedProducts に追加されるオブジェクトを検索および選択することです。
  3. ProductSearchPresenter のインスタンスを使用して、オブジェクトを検索および選択します。
    1. このユースケースの一部は、ProductEditPresenter のインスタンスを使用して、ProductSearchPresenter の選択されたオブジェクトを編集および保存することです。

これはユースケースの小さなコレクションにすぎませんが、私が抱えている問題はすでにたくさんあります。

  • ユースケース 1. と 2. は、同じ UI スレッドで同時に実行されます。
  • ユースケース 1.1。そして2.2。オブジェクトをロードしたプレゼンターが存在するよりも長く、このオブジェクトを使用する他のプレゼンターに選択されたオブジェクトを返します。
  • ユースケース 3.1。2.2./1.1.からロードされたオブジェクトを変更する可能性があります。3.1より前。が開始されましたが、2.2./1.1. 3.1より前にコミットされています。オブジェクトは保存され、3.1 を「ロールバック」することはできません。
4

1 に答える 1

2

これは、私たちの WinForms アプリケーション アーキテクチャ (MVP に基づく) に最も適しているとわかったものを簡単に示したものです。

すべてのプレゼンターは、必要なリポジトリに依存するコンストラクターです。たとえば、InvoicePresenter がある場合、依存関係として InvoiceRepository がありますが、複雑さに応じて、おそらく CustomerRepository と他の多くのものがあります (必要に応じて、すべての顧客を顧客コンボボックスにロードするための CustomerRepsitory があります)。請求書の顧客を変更するなど)。

次に、すべてのリポジトリに UnitOfWork のコンストラクタ引数があります。UnitOfWork パターンでセッションを抽象化するか、リポジトリを ISession に依存させることができます。

「コンテキスト」に基づいてプレゼンターを作成する IoC コンテナーによってすべてが接続されます。これは非常に単純な概念であり、コンテキストはプレゼンターごとおよびすべてのサブ プレゼンターであり、複雑さを軽減するために、より複雑なプレゼンターの複合ブロックとして作成します (たとえば、いくつかのエンティティまたは何かを編集するためのオプションの複数のタブがある場合)。

したがって、実際には、1 つのフォームが少なくとも 1 つのプレゼンター/ビューであるため、このコンテキストは 90% 時間フォーム ベースです。

だからあなたの質問に答えるために:

  1. プレゼンターごとのセッションと会話ごとのセッション (WinForms でも機能します) は、ここでは実際に使用できるパターンにすぎません (そして、あらゆる場所でクロージング セッションを開始しますが、それを処理するための実際には良い方法ではありません)-

  2. これは、リポジトリをプレゼンターではなくセッションに依存させることで解決するのが最善です。プレゼンターをリポジトリに依存させ、リポジトリをセッションに依存させ、すべてを作成するときに共通のセッションを与えます。しかし、繰り返しますが、これはコンテキスト内で行われる場合にのみ実用的です。請求書を編集する発表者と顧客を編集する別の発表者のセッションを共有することはできません。ただし、メイン プレゼンターと請求書の詳細と請求書メモのサブ プレゼンターを介して請求書を編集するときに、セッションを共有できます。

  3. 明確にしてください、これを理解していません...

于 2012-01-13T19:12:34.417 に答える