我正在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";
答案 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对象的情况下测试控制器。