如何设计ASP.NET控制器以利用Session同时便于进行单元测试?
- 内容介绍
- 文章标签
- 相关推荐
本文共计720个文字,预计阅读时间需要3分钟。
如何准备ASP.NET MVC控制器使用Session,同时保证可测试性?本质上,是否不使用Session而使用一些Session抽象?
我正在使用Ninject,因此示例可以基于此。问题是,Session对象在控制器中开始时不可用。
在ASP.NET MVC中使用Session,同时确保可测试性,通常涉及到对Session的直接依赖进行抽象。以下是一个简化的例子,展示如何使用Ninject来实现这一点:
csharppublic interface ISessionService{ object this[string key] { get; set; } bool TryGetValue(string key, out T value);}
public class SessionService : ISessionService{ public object this[string key] { get; set; }
public bool TryGetValue(string key, out T value) { if (HttpContext.Current.Session[key] !=null) { value=(T)HttpContext.Current.Session[key]; return true; } else { value=default(T); return false; } }}
public class ControllerWithSession : Controller{ private readonly ISessionService _sessionService;
public ControllerWithSession(ISessionService sessionService) { _sessionService=sessionService; }
// 使用SessionService来访问Session数据 public ActionResult SomeAction() { var value=_sessionService[SomeKey]; // 处理value return View(); }}
// 在Ninject配置中注册SessionServicepublic static class Bootstrapper{ public static void RegisterServices(IKernel kernel) { kernel.Bind().To(); // 其他服务绑定... }}
在这个例子中,`ISessionService` 接口定义了访问Session数据的方法,而 `SessionService` 类实现了这个接口,通过访问 `HttpContext.Current.Session` 来操作Session。
在控制器中,通过构造函数注入 `ISessionService` 来替代直接依赖 `HttpContext.Current.Session`。这样做的好处是,你可以在测试控制器时轻松地使用一个模拟的 `ISessionService` 实例,而不是实际的Session。
在测试环境中,你可以创建一个模拟的 `ISessionService`,它不依赖于 `HttpContext` 或 `Session`,从而使得测试更加灵活和可控。
这种方法允许你在保持应用性能的同时,确保你的控制器代码是可测试的。
如何准备ASP.NET MVC控制器使用Session同时是可测试的,所以本质上不使用Session而是使用一些Session抽象?我正在使用Ninject,因此您的示例可以基于此.问题是Session对象在控制器中始终不可用(如在ctor中),但我需要在应用程序启动时将某些内容存储到Session(global.asax.cs也无法访问Session).
您可以通过两种方法将实施/基础架构详细信息与控制器分开:
>次要抽象
public interface ISession { string GetValue(string name); void SetValue(string name, string value); }
>域抽象.
public interface IStateData { bool IsPresent { get; } int MyDomainMeaningfulVariable { get; set; } }
在后一种情况下,接口会在会话中添加语义 – 强类型,命名良好的属性.这与使用NHibernate域实体而不是sqlreader [“DB_COLUMN_NAME”]一样.
然后,当然,将接口的HTTP实现(例如,使用HttpContext.Current)注入控制器.
模型粘合剂也是一种很好的方法,就像动作过滤器一样.他们是not just for form data.
本文共计720个文字,预计阅读时间需要3分钟。
如何准备ASP.NET MVC控制器使用Session,同时保证可测试性?本质上,是否不使用Session而使用一些Session抽象?
我正在使用Ninject,因此示例可以基于此。问题是,Session对象在控制器中开始时不可用。
在ASP.NET MVC中使用Session,同时确保可测试性,通常涉及到对Session的直接依赖进行抽象。以下是一个简化的例子,展示如何使用Ninject来实现这一点:
csharppublic interface ISessionService{ object this[string key] { get; set; } bool TryGetValue(string key, out T value);}
public class SessionService : ISessionService{ public object this[string key] { get; set; }
public bool TryGetValue(string key, out T value) { if (HttpContext.Current.Session[key] !=null) { value=(T)HttpContext.Current.Session[key]; return true; } else { value=default(T); return false; } }}
public class ControllerWithSession : Controller{ private readonly ISessionService _sessionService;
public ControllerWithSession(ISessionService sessionService) { _sessionService=sessionService; }
// 使用SessionService来访问Session数据 public ActionResult SomeAction() { var value=_sessionService[SomeKey]; // 处理value return View(); }}
// 在Ninject配置中注册SessionServicepublic static class Bootstrapper{ public static void RegisterServices(IKernel kernel) { kernel.Bind().To(); // 其他服务绑定... }}
在这个例子中,`ISessionService` 接口定义了访问Session数据的方法,而 `SessionService` 类实现了这个接口,通过访问 `HttpContext.Current.Session` 来操作Session。
在控制器中,通过构造函数注入 `ISessionService` 来替代直接依赖 `HttpContext.Current.Session`。这样做的好处是,你可以在测试控制器时轻松地使用一个模拟的 `ISessionService` 实例,而不是实际的Session。
在测试环境中,你可以创建一个模拟的 `ISessionService`,它不依赖于 `HttpContext` 或 `Session`,从而使得测试更加灵活和可控。
这种方法允许你在保持应用性能的同时,确保你的控制器代码是可测试的。
如何准备ASP.NET MVC控制器使用Session同时是可测试的,所以本质上不使用Session而是使用一些Session抽象?我正在使用Ninject,因此您的示例可以基于此.问题是Session对象在控制器中始终不可用(如在ctor中),但我需要在应用程序启动时将某些内容存储到Session(global.asax.cs也无法访问Session).
您可以通过两种方法将实施/基础架构详细信息与控制器分开:
>次要抽象
public interface ISession { string GetValue(string name); void SetValue(string name, string value); }
>域抽象.
public interface IStateData { bool IsPresent { get; } int MyDomainMeaningfulVariable { get; set; } }
在后一种情况下,接口会在会话中添加语义 – 强类型,命名良好的属性.这与使用NHibernate域实体而不是sqlreader [“DB_COLUMN_NAME”]一样.
然后,当然,将接口的HTTP实现(例如,使用HttpContext.Current)注入控制器.
模型粘合剂也是一种很好的方法,就像动作过滤器一样.他们是not just for form data.

