【问题标题】:Cannot get a working Unity Session Lifetime Manager, ASP.NET MVC5无法获得正常工作的 Unity 会话生命周期管理器,ASP.NET MVC5
【发布时间】:2015-06-23 16:14:13
【问题描述】:

我已阅读并在 Google 上搜索了所有内容,但似乎无法让它发挥作用。我根据这些帖子在我的 MVC5 应用程序中为 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 RemoveValue()
    {
        HttpContext.Current.Session.Remove(key);
    }

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

我只玩了几个类型,这里是UnityConfig.cs中的相关注册:

container.RegisterType<IEpiSession, EpiSession>(new SessionLifetimeManager(), 
    new InjectionConstructor(config.AppServerURI, config.PathToSysConfig));
container.RegisterType<IReportRepository, EpicorReportRepository>(new TransientLifetimeManager());

DependencyResolver.SetResolver(new UnityDependencyResolver(container));

请注意,EpicorReportRepository 通过构造函数注入依赖于IEpiSession。

public class EpicorReportRepository : IReportRepository
{
    private IEpiSession session;

    // DI constructor
    public EpicorReportRepository(IEpiSession session) {
        this.session = session;
    }
// ...
}

我的问题:在第一个用户/会话连接到应用程序后,之后的每个新用户/会话似乎仍在使用第一个用户创建的 EpiSession 对象和凭据/为他注射。这似乎是互联网上使用的常见模式,所以我想知道我错过了什么。

【问题讨论】:

    标签: asp.net-mvc dependency-injection asp.net-mvc-5 unity-container


    【解决方案1】:

    您如何测试IEpiSession 在不同的Sessions 中是否相同?

    尝试从不同的浏览器打开您的应用程序。如果您在同一个浏览器中打开多个选项卡,则会使用同一个会话。

    我检查了您的代码,它对我有用。 SetResolver()只有一个区别:

    DependencyResolver.SetResolver(
        type => container.Resolve(type),
        types => container.ResolveAll(types));
    

    完整的注册码如下:

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            ...
            var container = new UnityContainer();
            container.RegisterType<IEpiSession, EpiSession>(
                new SessionLifetimeManager(),
                new InjectionConstructor("config.AppServerURI", "config.PathToSysConfig"));
            container.RegisterType<IReportRepository, EpicorReportRepository>(new TransientLifetimeManager());
    
            DependencyResolver.SetResolver(
                type => container.Resolve(type),
                types => container.ResolveAll(types));
        }
    }
    

    【讨论】:

    • Ilya,我假设你是对的,没有时间测试这个,但它证实了我的怀疑 - 真正的 EpiSession 对象是第 3 方,我认为它是即使内存中有两个不同的 EpiSession 对象(每个会话一个),也可以在连接池或共享的引擎盖下做一些事情。我肯定有两个会话,用一些调试代码检查过,但我还没有测试我是否有两个单独的 EpiSession 对象 - d'uh。我敢打赌它会证明我这样做了,就像我说的那样——只需要弄清楚为什么它只使用一个与 ERP 系统的连接。
    • @AdamNofsinger,好吧,您可以将 EpiSession 的生命周期更改为 Transient 并检查这些实例将如何工作。它可能会帮助您验证您的假设。
    猜你喜欢
    • 2010-10-16
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 2015-03-30
    相关资源
    最近更新 更多