2009-06-11 15 views
2

私は、 "Micorosoft.Practices.Unity"と "Microsoft.Practices.ObjectBuilder2"のDependency Injections機能を利用するasp.net mvc Webサイトを持っています。これはすべて私のオブジェクトを私のコントローラのコンストラクタに挿入することで素晴らしいものです。UnityContainerセッション状態でのASP.NET MVC依存性注入

問題は、ユーザーがブラウザを離れたりログオフしたりするときにこのセッションをクリアするのが難しいことです。すべての値はオブジェクト内に保持されたままです。どのようにしてSession_End()のglobal.asaxで作成されたコンテナをデリートするか、ユーザーがクリックしてコントローラの操作で気を配ります。

以下はいくつかのサンプルコードです。

Global.asaxからSession_startから実行は:

protected static void RegisterDependencies() 
{ 
    IUnityContainer container = new UnityContainer(); 

    container.RegisterType<DataStore, DataStore>(new SessionLifetimeManager<DataStore>()); 
    container.RegisterType<IMotorRepository, MotorRepository>(new SessionLifetimeManager<IMotorRepository>()); 
    container.RegisterType<ICoverRepository, CoverRepository>(new SessionLifetimeManager<ICoverRepository>()); 
    container.RegisterType<IDriverRepository, DriverRepository>(new SessionLifetimeManager<IDriverRepository>()); 
    container.RegisterType<IVehicleRepository, VehicleRepository>(new SessionLifetimeManager<IVehicleRepository>()); 
    container.RegisterType<ICodeValueRepository, CodeValueRepository>(new SessionLifetimeManager<ICodeValueRepository>()); 

    ControllerBuilder.Current.SetControllerFactory(
     new UnityControllerFactory(container) 
    ); 
} 

SessionLifeTimeManager

public class SessionLifetimeManager<T> : LifetimeManager, IDisposable 
{ 
    public override object GetValue() 
    { 
     return HttpContext.Current.Session[typeof(T).AssemblyQualifiedName]; 
    } 
    public override void RemoveValue() 
    { 
     HttpContext.Current.Session.Remove(typeof(T).AssemblyQualifiedName); 
    } 
    public override void SetValue(object newValue) 
    { 
     HttpContext.Current.Session[typeof(T).AssemblyQualifiedName] = newValue; 
    } 
    public void Dispose() 
    { 
     RemoveValue(); 
    } 
} 
+1

おそらく私は間違っていますが、あなたはセッションごとのコンテナを持っているように、あなたがしていることを恐ろしいように見せています。まず、「SetControllerFactory」を別の場所で呼び出すロジックがない限り、 SetControllerFactoryは、セッション全体ではなく、アプリケーション全体のコントローラファクトリを設定するため、怪我のために準備する必要があります。 – meandmycode

答えて

0

のSession_Endは、ユーザーの葉の後に30分のようなものまで、解雇されていません。私はあまりにもASP.NETのセッションの悲惨さに会った。

Session.Abandonを呼び出すと、強制的にSession_endを開始できます。ユーザーがサイトを離れたり、ブラウザを閉じたりしても、問題は解決しません。

javacriptイベントを使用し、ページを終了するときにセッションを終了するためにWebサービス呼び出しを行うことができます。これは、作業を保存する前にユーザーが離脱しないようにしようとするのと同じロジックです。

この問題はありますか?すべてのページ遷移がセッションの有効期限切れになります。

window.onbeforeunload = endSession; 

function endSession() { 
    //end session here through some kind of call back to the server 
} 

私は(ポストバックのような)他の人がイベントを発生さないだろうがどこ一部の機能は、残してからユーザーを抑止するポップアップを引き起こす、しかし、前に単一のページを行っています。私がやらなければならなかったことは、ページの読み込みにvarを設定し、特定のコントロールやリンクが相互作用するときにそのvarを変更することです。これは非常に侵襲的な実装であり、広いサイトを実装するために、仕事との統合の多くが必要ですが、それが動作することができます

var endUserSession = true; 

window.onbeforeunload = endSession; 

function endSession() { 
    if(endUserSession) { 
     //end session here through some kind of call back to the server 
    } 
} 

、それは時間あなたのポストバックがセッション終了をトリガしないように取得することがかかりますが。

私の個人的な経験では、セッションを処理して、それが期限切れであるか期限切れではないか心配するのは最善です。セッションの周りの問題を解決しようとするのに費やされた時間が長すぎます。 IISはそれを処理しなければなりません。そして、ワーカープロセスに入り、WPが再起動される(セッションがクリアされる)頻度を変更することができます。

問題が利用可能なシステムリソースに関連している場合、つまりサイトが多量のメモリを占有しており、ダンプセッションがオプションではない場合は、SQL Server State Serverを実装してから、欲しいです。

How to implement sql state server

0

最初のコメンターが示唆したこのアプローチ、との問題は、両方のセッションに関連付けられたコンテナを作成し、セッションにそのコンテナに関連するオブジェクトの寿命を設定しているということです。

本当に、両方を行う必要はありません。コンテナをセッションに関連付けるか、オブジェクトの有効期間をセッションに設定するかのいずれかを登録します。

私はコンテナの作成をよりきれいに保つので、オブジェクトの有効期間をセッションに設定することをお勧めします。コンテナの作成をアプリケーションレベルに移すだけです。ユーザ(すなわち一意のセッション)が、コンテナに登録されたタイプのオブジェクトを要求し、そのオブジェクトの存続期間がセッションである場合、そのユーザのセッションでそのオブジェクトを探す。見つからなければ、それをセッションに追加します。見つかった場合は、セッションから返されます。別のユーザーが同タイプのオブジェクトを要求した場合、オブジェクトのバッキングストアが各ユーザーごとに一意であるため、同じパターンが発生します。