如何设计ASP.NET控制器以利用Session同时便于进行单元测试?

2026-03-30 13:011阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计720个文字,预计阅读时间需要3分钟。

如何设计ASP.NET控制器以利用Session同时便于进行单元测试?

如何准备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).

如何设计ASP.NET控制器以利用Session同时便于进行单元测试?

如果您希望您的类可以测试,请不要在那里使用不可测试的(外部)组件.当你试图模仿它们时,你只需要解决这个糟糕的设计.改为重新设计控制器.类不应该依赖外部/全局对象.这就是使用IoC的原因之一.

您可以通过两种方法将实施/基础架构详细信息与控制器分开:

>次要抽象

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控制器以利用Session同时便于进行单元测试?

如何准备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).

如何设计ASP.NET控制器以利用Session同时便于进行单元测试?

如果您希望您的类可以测试,请不要在那里使用不可测试的(外部)组件.当你试图模仿它们时,你只需要解决这个糟糕的设计.改为重新设计控制器.类不应该依赖外部/全局对象.这就是使用IoC的原因之一.

您可以通过两种方法将实施/基础架构详细信息与控制器分开:

>次要抽象

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.