2009-06-11 62 views
2

我有一個asp.net mvc網站,我使用「Micorosoft.Practices.Unity」和「Microsoft.Practices.ObjectBuilder2」的依賴注入功能。這一切都很好,將我的對象注入到我的控制器構造函數中。ASP.NET MVC依賴注入與UnityContainer會話狀態

問題是,當用戶離開瀏覽器或想要註銷時,我很難清除此會話。所有的值都保留在對象中。我該如何取消在global.asax中創建的容器,或者是由用戶點擊並由控制器操作保管的Session_End()

下面是一些示例代碼。

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 2009-06-14 20:36:51

回答

0

Session_End中沒有發射,直到像在用戶離開後30分鐘。我也遇到了ASP.NET中會話的困境。

如果您調用Session.Abandon,則可以強制觸發Session_end。但是,如果用戶離開您的網站或關閉瀏覽器,這並不能解決您的問題。

你可能也許使用JavaScript事件,並做一個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狀態服務器,然後重新啓動工作進程想。

How to implement sql state server

0

這種方法,其中第一個評論者提到的問題是,你們都創造相關的會話容器和設置關聯到該容器會話對象的壽命。

真的,你不需要同時做這兩件事。要麼註冊將容器與會話相關聯,要麼將對象的生命週期設置爲會話。

我更喜歡將對象的生命週期設置爲會話,因爲它使我的容器創建更清潔。只需將您的容器創建移動到應用程序級別。當用戶(即唯一會話)要求向容器註冊的類型的對象並且該對象的生命週期是會話時,它將在該用戶的會話中查找該對象。如果找不到,它會將其添加到會話中。如果發現它會從會話中返回。如果另一個用戶出現並請求相同類型的對象,則會出現相同的模式,因爲該對象的後備存儲對於每個用戶都是唯一的。