English 中文(简体)
使用ASP.NET会话管理寿命(Unity)
原标题:
  • 时间:2009-04-01 20:07:46
  •  标签:

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

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

问题回答

使用ASP.Net MVC和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的生命周期。

为什么不使用缓存对象呢,这样你就可以在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上都可以正常工作。

我认为你需要通过Unity公开两个服务(或一个执行两个操作的服务)。

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

您还需要一个设置方法/属性,用于设置用户。

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

将此翻译成中文:http://martinfowler.com/eaaCatalog/registry.html http://martinfowler.com/eaaCatalog/registry.html

也许我想太多了,但我认为你应该在IoC中使用AoP。这实际上是一种非常美妙的配对方式。基本上,我会劫持你要解决的类的构造函数,也就是说创建一个方面。然后你可以在进入构造函数时将用户注入到类中,但任何解决类的东西都不必明确提供用户,从而防止与Unity本身的配对。

在我看来,PostSharp是一款出色的AoP框架。

现在最终您的应用程序将依赖于AoP框架,但完全解耦的应用程序可能取决于您的环境而不现实。您可能会惊讶于AoP和IoC的组合可以有多么有用。

如果你说的“自定义ASP.NET会话管理器”是指NHibernate会话或Data/ObjectContext,那么你需要的是一个注入到构造函数或属性设置器中的IUserRepository,从中你可以检索到用户对象。IUserRepository的实现可以是任何内容,从数据库访问到后端缓存等。如果你直接在容器上使用.Resolve(),你正在遵循“服务定位器”模式,而没有正确使用Unity所能提供的全部功能。

你可以使用Ravi的回答来管理存储库的生存周期。





相关问题
热门标签