2011-03-17 104 views
1

我使用的是MVC 3,根據不同的存儲庫我有一系列控制器,我的存儲庫中有一個依賴於http上下文會話。 爲了使用Windsor-Castle IoC,我爲每個存儲庫創建了接口。Windsor Castle IoC - Http Session

如何將當前會話對象傳遞給需要它的存儲庫?

我曾經是能夠做到這一點和「解決」會照顧會話傳遞給需要它的存儲庫中,不知何故,我不能在最新版本中做到這一點(2.5.3 2011年2月):

Protected Overrides Function GetControllerInstance(ByVal requestContext As System.Web.Routing.RequestContext, _ 
                ByVal controllerType As System.Type) As System.Web.Mvc.IController 
    Dim match As IController 
    ' 1 or more components may need the session, 
    ' adding it as a (possible) dependency 
    Dim deps As New Hashtable 
    deps.Add("session", HttpContext.Current.Session) 
    match = container.Resolve(controllerType, deps) 
    Return match 
End Function 

謝謝,文森特

回答

2

控制器廠的唯一責任是創建控制器。不處理會話或任何其他依賴項。最好只將會話註冊爲一個單獨的組件,讓Windsor自動裝配它。從那裏取出 'DEPS' Hashtable和註冊:

container.Register(Component.For<HttpSessionStateBase>() 
     .LifeStyle.PerWebRequest 
     .UsingFactoryMethod(() => new HttpSessionStateWrapper(HttpContext.Current.Session))); 

然後在你的控制器注入HttpSessionStateBase

順便說一下:控制器已經可以訪問會話,如果您只是將會話注入控制器,則不需要這樣做。

4

仔細看看你的設計。當你仔細觀察它時,你的存儲庫根本不依賴於會話,而是存儲在會話中的某些數據。針對要從會話中提取的內容創建抽象,並讓存儲庫依賴於這種抽象。例如:

public interface IUserProvider 
{ 
    int GetCurrentUserId(); 
} 

public class SomeRepository : ISomeRepository 
{ 
    private readonly IUserProvider userProvider; 

    public SomeRepository(IUserProvider userProvider) 
    { 
     this.userProvider = userProvider; 
    } 
} 

現在,您可以創建以下實現,抽象的:

private class HttpSessionUserProvider : IUserProvider 
{ 
    public int GetCurrentUserId() 
    { 
     return (int)HttpContext.Current.Session["UserId"]; 
    } 
} 

你可以在你的IoC配置寄存器這個具體類型。

這樣好多了,因爲您不想讓存儲庫直接依賴HTTP會話。這使測試變得更加困難,並在您的存儲庫和特定的演示技術之間創建依賴關係。