2011-06-20 14 views
0

DaoとIoCという新しいパターンを試してみるサンプルプロジェクトを作成しました。Castle.Windsorとデータアクセスオブジェクトwebforms asp.net

マイダオは、次のように定義されています。私は、引数としてIDao<MyClass> myClassを受け入れるコンストラクタを持つコントローラを定義することができますMVCパターンを使用して

public class DaoInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(Component.For(typeof(Data.IDao<>)) 
      .ImplementedBy(typeof(Data.Dao<>)) 
      .ServiceOverrides(ServiceOverride.ForKey("SessionFactory").Eq("FirstSessionFactory")) 
      .Named("FirstDao")); 
    } 
} 

public class Dao<T> : IDao<T> 
{ 
    protected NHibernate.ISessionFactory _sessionFactory; 

    public Dao(NHibernate.ISessionFactory sessionFactory) 
    { 
     this._sessionFactory = sessionFactory; 
    } 

    protected NHibernate.ISession Session 
    { 
     get { return _sessionFactory.GetCurrentSession(); } 
    } 

    public T GetById(object id) 
    { 
     return Session.Get<T>(id); 
    } 

    ... 
} 

をそして、私は、対応するインストーラを持っていますWindsorは私のために正しいSessionFactoryでDaoをインスタンス化するすべての魔法を実行します。私の質問は、非MVC環境で同じ振る舞いを達成するにはどうすればいいですか?どの特定のページでも、どのようにmyClassのインスタンスを取得できますか?

+0

[この回答](http://stackoverflow.com/questions/293790/how-to-use-castle-windsor-with-asp-net-web-forms)が役立つことがあります。 –

答えて

2

MVCより前では、ASP.NetはIoCパターンを使用するように構築されていませんでした。 MVCはIoCに対応しており、Windsorや他のIoC実装がMVCフレームワークにプラグインして、MVCのデフォルト工場から完全に構成されたコントローラをインスタンス化する作業を引き継ぐ拡張ポイントがあります。 Webフォームサイトには、ページクラスをインスタンス化する機能はありません。

WebフォームプロジェクトでNHibernateを使用するには、HttpRequestのItemsコレクションを使用する必要があります。通常は、要求がPageクラスによって処理される前後にコードを実行するHttpModuleを使用します。要求の開始時に、モジュールはNHibernateセッションを作成し、それをリクエストのItemsコレクション(ASP.Netに置くことができる唯一の場所)に配置します。その後、ページ上のコードはセッションで取得できます。ページクラスは、必要に応じてIDao実装をインスタンス化し、セッションをその中に渡します。リクエストの最後に、モジュール内のコードがセッションをフラッシュして閉じます。このようにして、すべてのセッション管理は、ページハンドラ内のコードに対して透過的に処理されます。 (これは、MVCとSharp Architectureフレームワークに切り替える前に私が行ったことです。それはちょうど正しかったインフラストラクチャコードの多くでした;私はシャープアーキテクチャを代わりに使用してうれしく思います。

WebフォームプロジェクトでIoCコンテナを使用することはできますが、完全に透過的ではありません。 IDaoの実装を明示的にコンテナに依頼することができます。 IDo実装をIDo実装に提供するようにIoCコンテナを設定し、Webリクエストごとのセマンティクスでセッションの有効期間を管理するようにIoCコンテナを設定する必要があります。しかし、MVCのようにきれいではありません。コントローラのコードにはこれがありません。

+0

DIを "シミュレート"する方法のコードサンプルをいくつか用意してください。現時点では、必要なセッションをHttpContextから取得することしか考えられませんが、その場合、Windsorはちょうどボルトであり、厳密には必要ではありません。 – Shagglez

+0

Krzysztofの答えのリンクは面白そうです。 Windsor Webサイトの検索結果から、WebアプリケーションでNHibernateを使用するためのHttpModuleがあることがわかります。http://www.castleproject.org/container/facilities/trunk/nhibernate/webapp.html –

0

ありがとうございました。残念なことに、私はフィールドで非常に限られているため(私の手には時間が限られています)、私は今までよりもさらに混乱しています。私が理解したことから、WebフォームはIoCで使われることは意図されておらず、回避策は存在しますが、かなり複雑です。 プロジェクトをMVCに移行するまでWindsorを放棄すると思いますが、今は単純なstatic SessionManagerクラスを使用しています。

SessionManagerのは、その後のように定義App_Init、中にSessionFactoriesContainerをインスタンス化する責任がある:

として定義
public static readonly Dictionary<string, ISessionFactory> SessionFactoriesContainer = new Dictionary<string, ISessionFactory>(); 

SessionsContainer

SessionsContainerものの
public static Dictionary<string, ISession> SessionsContainer 
    { 
     get 
     { 
      Dictionary<string, ISession> sessionContainer = (Dictionary<string, ISession>)HttpContext.Current.Items[SESSION_CONTAINER_KEY] ?? new Dictionary<string, ISession>(); 
      foreach (FactoryType type in Enum.GetValues(typeof(FactoryType))) 
      { 
       if (!sessionContainer.ContainsKey(type.ToString())) 
        sessionContainer.Add(type.ToString(), null); 
      } 
      HttpContext.Current.Items[SESSION_CONTAINER_KEY] = sessionContainer; 
      return sessionContainer; 
     } 
    } 

私の理解があることであるのHttpContextに保存されていることから、静的です各ユーザーは自分のコンテナを持っていますが、これを前提に間違っていますか?

SessionManagerにはまた、定義されたクラスGetSessionForがあります

public static ISession GetSessionFor(FactoryType type) 
    { 
     ISession session = SessionsContainer[type.ToString()] ?? SessionFactoriesContainer[type.ToString()].OpenSession(); 
     session.BeginTransaction(); 
     SessionsContainer[type.ToString()] = session; 

     return session; 
    } 

新しいリポジトリが必要で、ISessionはその後、コンストラクタに渡されるたびに呼び出されます。要求の最後に、オープンセッションごとにコミットされるか、エラーが発生した場合にトランザクションがロールバックされます。

これは非常に粗末な実装であることがわかりましたが、うまくいくはずです。私がプロジェクトの終わりに時間があれば、セッション管理を再訪し、うまくインストーラを実装することを目指します。その間に誰か他のアイデアがある場合は、自由に追加してください。

関連する問題