如何从Web应用程序层下面的层访问会话值

时间:2010-04-23 22:52:36

标签: asp.net session separation-of-concerns

我们的应用程序中有许多实例,我们希望能够访问业务域和数据访问层中当前登录的用户ID等内容。在日志中,我们将此信息推送到会话,因此我们所有的前端代码当然都可以非常轻松地访问它。但是,我们在应用程序的较低层中获取数据时遇到了很大的问题。我们似乎无法找到一种方法来在业务域中存储一个仅为用户具有全局范围的值(静态类和属性当然由应用程序域共享,这意味着会话中的所有用户只共享一个对象的副本)。我们已经考虑将会话传递给我们的业务类,但是我们的域与我们的Web应用程序紧密耦合。我们希望继续保持应用程序的winforms版本的前景。

我发现很难相信我们是第一个遇到这类问题的人。您是如何在应用程序中处理此问题的?

3 个答案:

答案 0 :(得分:3)

我认为让您的业务类依赖于全局对象并不是一个好主意,并且如果可能的话会避免使用它。您向其中注入必要的信息 - 这使它们更具可测性和可扩展性。

因此,不应将Session对象直接传递给它们,而应将所需的信息访问方法包装到存储库类中。您的业​​务层可以使用存储库类作为数据源(例如,在其上调用GetUser()),并且您的Web应用程序的存储库可以使用会话来检索所请求的信息(返回_session.User.Identity)。

将其移植到winforms时,只需使用一个新的以winform为中心的类实现存储库接口(即GetUser()返回用户主体的Windows版本。)

答案 1 :(得分:1)

理论上,人们会告诉你这是一个糟糕的商业行为。 实际上,我们只需要业务层中可用的会话级数据。 : - (

我们最终在一个小型界面下将不同的存储引擎联合起来。

public interface ISessionStorage 
{
   SomeSessionData Data {get;set;}
   ...
   .. and most of the data we need stored at "session" level
    }
 //and a singleton to access it
    public static ISessionStorage ISessionStorage;

这个界面几乎可以在我们代码的任何地方使用。

然后我们有一个Session和/或一个单例实现

 public WebSessionStorage
{
   public SomeSessionData Data 
  {
       get { return HttpContext.Current.Session["somekey"] as SomeSessionData;}
      set { HttpContext.Current.Session["somekey"] = value;}
  }

public WebFormsSessionStorage
{
   private static SomeSessionData  _SomeSessionData; //this was before automatic get;set;
   public SomeSessionData 
   {
       get{ return _SomeSessionData;}
       set{ _SomeSessionData=value; }
}

}

在启动申请时,网站将进行

 Framework.Storage.SessionStorage = new WebSessionStorage(); 
在Global.asax中

,而FormsApp将执行

 Framework.Storage.SessionStorage = new WebFormsSessionStorage(); 

答案 2 :(得分:0)

我完全赞同Womp - 将数据从你的前端注入你的下层。

如果你想做一个中途作弊(但不是太多的作弊),你可以做的是用一对POCO classes创建一个非常小的组件来存储你想要的所有这些信息分享所有层级(当前登录的用户名,登录时间等),然后将此对象从您的前端传递到您的业务/数据层。现在,如果你这样做,你必须避免诱惑将这个POCO组件变成一个通用的公用事业组件 - 它必须保持小或者你将来会遇到问题(相信我或学习困难的方法或者请别人详细说明这个问题)一)。但是,如果你有这个POCO程序集,通过各个层注入这些数据变得非常容易,因为它是POCO,它可以很好地序列化并且可以很好地与Web服务,WCF等一起工作。