使用静态类处理会话数据
本文关键字:会话 数据 处理 静态类 | 更新日期: 2023-09-27 18:25:51
我手头有一个Windows窗体应用程序,其中GUI和业务逻辑有明确的分离。这个解决方案很大(40个项目,数千个类,大约2000个数据库表)。我的任务是找到一个关于如何重用业务逻辑以构建web应用程序作为前端的解决方案。
我认为,主要的问题是我们的静态会话类,它被解决方案中的其他所有类使用:
public static class Session
{
public static string CurrentUser { get; set; }
public static string CurrentDatabase { get; set; }
public static string CurrentCompanyProfile { get; set; }
public static string CurrentLanguage { get; set; }
}
这个类在ASP.NET中不起作用,因为它将由所有用户共享,而且我无法替换它,因为它被大量使用。
我想我需要从这个类中删除所有信息,只保留接口。通过调用属性代码的get方法,将以某种方式将此调用重定向到HttpContext.Current.Session,在那里我将存储一个包含所有这些信息的类。
考虑到Session驻留在一个不会引用System.Web的程序集中,并且考虑到我不能破坏我们的WinForms实现,我不知道如何正确地执行此操作。
谢谢。
假设您可以更新Session类,则可以抽象Session类中属性的存储。在当前应用程序中,您可以创建一个简单的内存存储,在web应用程序中您可以创建web会话存储。
首先定义一个会话值提供程序,您可以在当前的静态会话类中使用它。
public interface ISessionValueProvider {
string CurrentUser { get; set; }
string CurrentDatabase { get; set; }
string CurrentCompanyProfile { get; set; }
string CurrentLanguage { get; set; }
}
public static class Session {
private static ISessionValueProvider _sessionValueProvider;
public static void SetSessionValueProvider(ISessionValueProvider provider) {
_sessionValueProvider = provider;
}
public static string CurrentUser {
get { return _sessionValueProvider.CurrentUser; }
set { _sessionValueProvider.CurrentUser = value; }
}
// Etc for the other props
}
对于当前的应用程序,定义一个使用内存存储值的sesion值提供程序。
public class MemorySessionValueProvider: ISessionValueProvider {
public string CurrentUser {get; set; }
// Etc for the other props
}
要使用它,请创建一个实例并将其提供给静态会话类。例如,您可以将其添加到Main方法中。
Session.SetSessionValueProvider(new MemorySessionValueProvider());
现在,对于您的web应用程序,创建一个使用web会话的会话值提供程序。
public class WebSessionValueProvider: ISessionValueProvider {
private const string CURRENTUSERKEY = "CurrentUser"; // TODO: Change this if necessary
public string CurrentUser {
get { return (string)HttpContext.Current.Session[CURRENTUSERKEY]; }
set { HttpContext.Current.Session[CURRENTUSERKEY] = value; }
}
// Etc for the other props
}
再次,将此web会话值提供程序的实例提供给静态会话类。例如,在global.asax.
Session.SetSessionValueProvider(new WebSessionValueProvider);
我会使用IoC容器(例如Castle Windsor)。声明一个接口,例如IStateManager
:
public interface IStateManager
{
T GetItem<T>(string key);
SetItem<T>(string key, T value);
}
然后,Session
类的实现将发生如下变化:
public static class Session
{
private static IStateManager _manager;
private static IStateManager Manager
{
get
{
if (_manager == null)
{
IStateManager m = null; // Get instance using IoC container
Interlocked.CompareExchange(ref _manager, m, null);
}
return _manager;
}
}
public static string CurrentUser
{
get { return Manager.GetItem<string>("CurrentUser"); }
set { Manager.SetItem<string>("CurrentUser", value); }
}
// The rest is similar
}
对于WinForms,该实现将只在静态实例上操作,而对于ASP.NET,您将有一个不同的实现来维护会话中的数据。好处是,对于不同的环境,您只需要有不同的安装程序,并且您的代码根本不需要了解它们(因此,逻辑将不依赖于WinForms或ASP.NET)。
此外,这种方法是可测试的(例如,使用Moq模拟IStateManager
非常容易)。