如何在DI项目中使用Session提供程序

时间:2015-04-20 17:39:20

标签: asp.net-mvc session dependency-injection inversion-of-control session-state

我正在ASP.NET MVC5中开发一个Web应用程序。

与所有基本Web应用程序一样,它也有一个登录页面,用户可以在其中进行身份验证。一旦通过身份验证,我想在Session中存储几个与用户相关的项目,这样我就不必每次都要查询数据库来重建经过身份验证的用户。

在阅读了Mark Seemann关于依赖注入的书之后,我想松散地结合我的所有层,并确保一切都可以轻松替换。

目前我的SessionProvider默认使用Session对象,但未来可能会改为另一种存储机制。

我采用的方法是使用 Ambient Context ,他用 TimeProvider 示例解释,但我想知道这是否是这种功能的正确方法,如果它是线程安全的(也用于单元测试)。

我的解决方案是否正确或您将如何实施这样的机制?这已经有好几天了,所以谁可以帮我定义最佳解决方案?

谢谢!

public abstract class SessionProvider
{
    private static SessionProvider _current;

    static SessionProvider()
    {
        _current = new DefaultSessionProvider();
    }

    public static SessionProvider Current
    {
        get { return _current; }
        set
        {
            if (value == null)
            {
                throw new ArgumentNullException();
            }
            _current = value;
        }
    }

    public abstract string UserName { get; set; }
}

我的本​​地默认值:

public class DefaultSessionProvider : SessionProvider
{
    public override string UserName
    {
        get { return (string) HttpContext.Current.Session["username"]; }
        set { HttpContext.Current.Session["username"] = value; }
    }
}

所以我可以访问我的SessionProvider的整个解决方案,无论这是真正的会话对象还是数据库驱动的存储机制......

SessionProvider.Current.UserName = "myUserName";

1 个答案:

答案 0 :(得分:0)

  

经过身份验证后,我想存储一些与用户相关的项目   会话,所以我不必每次都查询数据库   重建经过身份验证的用户。

好吧,看起来你正在研究某种缓存机制。如果它在Session或Redis缓存中,或任何其他类型的缓存中并不重要。这个缓存是键值存储。我会创建缓存接口,类似于:

interface ICache
{
     object this[string key] {get; set;}
}

创建具体的课程。在你的情况下SessionCache:

public SessionCache : ICache
{
    private IHttpSessionState _session;
    public SessionCache(IHttpSessionState session)
    {
        _session = session;
    }

    // ICache implementation goes here...
}

因此,您将问题范围缩小为依赖性 - 将Session对象注入具体类(SessionCache)。使用Ninject,您可以执行以下操作:

.WithConstructorArgument("session",ninjectContext=>HttpContext.Session);

之后,您最终可以使您的控制器依赖于ICache。

在您的单元测试项目中,您可以创建另一个ICache具体类,类似于具有内存缓存的DummyCache。因此,您可以在不遵守Session对象的情况下测试控制器。