使用ASP.NET Session进行终身管理(Unity)

时间:2009-04-01 20:07:46

标签: c# asp.net session unity-container

我正在考虑使用Unity来管理自定义用户类实例的生命周期。我计划使用自定义ASP.NET会话管理器扩展LifetimeManager。我希望能够做的是从我的自定义类存储和检索当前登录的用户对象,并让Unity从ASP.NET中的会话对象获取User的实例,或者(在Win32项目中时)检索它静态地或从当前线程。

到目前为止,我最好的解决方案是在启动时创建Unity容器的静态实例,并使用Resolve方法从我的每个类中获取User对象。但是,这似乎在我的其他类中创建了对unity容器的依赖。实现这一目标的“团结”方式是什么?我希望能够从任何类中读取/替换当前的User实例。

7 个答案:

答案 0 :(得分:15)

当与ASP.Net MVC一起使用而不是普通的旧ASP.Net项目时,你会获得Unity的最佳效果。 ASP.Net MVC允许您使用像Unity这样的容器来管理用户对象,控制器,模型等。如果可能,请为您的项目使用MVC而不是ASP.net Web表单。

如果我正确理解您的问题,您可能希望使用Unity来维护每个会话对象的生命周期。您需要实现扩展LifetimeManager的SessionLifetimeManager。代码非常简单,并且遵循这些方针:

public class SessionLifetimeManager : LifetimeManager
{
    private string _key = Guid.NewGuid().ToString();

    public override object GetValue()
    {
          return HttpContext.Current.Session[_key];
    }

    public override void SetValue(object value)
    {
          HttpContext.Current.Session[_key] = value;
    }

    public override void RemoveValue()
    {
          HttpContext.Current.Session.Remove(_key);
    }
}

您也可以为PerWebRequest终身管理编写类似的文件。

答案 1 :(得分:2)

为什么不使用缓存对象...然后你可以从win和web使用它。像这样:

    IUnityContainer container= HttpRuntime.Cache.Get("Unity") as IUnityContainer;

    if (container == null)
    {
        container= // init container

        HttpRuntime.Cache.Add("Unity",
            container,
            null,
            Cache.NoAbsoluteExpiration,
            Cache.NoSlidingExpiration,
            CacheItemPriority.NotRemovable,
            null);
    }

    // return container or something

HttpRuntime.Cache将在win和web

中运行

答案 2 :(得分:0)

我认为您需要通过统一公开的两种服务(或者一种服务同时执行这两种操作)。

不存储用户对象,而是存储一个接口实现,该实现公开了一个方法/属性,它将为您获取用户对象。在ASP.NET的情况下,您从会话中检索用户。在WinForm解决方案(或其他)中,您可以从正在执行的线程中获取它。

您也可以使用set方法/属性来设置用户。

答案 3 :(得分:0)

听起来实际上你需要注册表模式,而不是Unity。

http://martinfowler.com/eaaCatalog/registry.html

答案 4 :(得分:0)

也许我在想这个,但我认为你应该使用AoP和IoC。这真是一个美丽的配对。基本上我要做的是劫持你正在解析的类的构造函数,否则称为创建一个方面。然后,您可以在进入构造函数时将用户注入到类中,但是解析类的任何内容都不会明确地提供用户,从而阻止与Unity本身配对。

PostSharp是一个出色的AoP框架恕我直言。

现在最终您的应用程序将依赖于AoP框架,但根据您的环境,完全分离的应用程序可能不切实际。你可能会惊讶于AoP和IoC的结合是多么有用。

答案 5 :(得分:0)

如果您通过“自定义ASP.NET会话管理器”讨论NHibernate会话或Data / ObjectContext,那么您需要的是将IUserRepository注入到构造函数或属性setter中,您可以从中检索用户对象。 IUserRepository的实现可以是从数据库访问到后端缓存等的任何内容。如果您直接在容器上使用.Resolve(),则表示您遵循Service Locator模式并且没有正确使用Unity提供。

然后,您可以使用Ravi's answer来管理存储库的生命周期。

答案 6 :(得分:-5)

如果这不太正确,我很抱歉......

Unity是一个游戏开发平台,因此我假设您正在构建一个3D应用程序或游戏,您打算做一些很酷的事情(例如,使用服务器让多人游戏/跟踪用户进步)。

为什么不让每个用户登录,然后您可以使用MembershipProvider和Formsauthentication类来获取对用户ID /名称的访问权限。

在您的服务器上,您只需将所有信息链接到用户的信息,即可轻松撤回(简单的ajax /普通http请求)与情况/用户请求相关的数据。

我不确定这一点,但我相信统一是部署客户端的东西,因此不需要在服务器上进行集成。

只需提出您需要的内容并在客户端进行处理。

通过这种方式,您可以坚持使用经典的n层设计模式,从而将逻辑与数据存储和ui分开。

希望这会有所帮助......