我需要我的控制器在会话之间存储数据。因此,如果在会话期间将数据保存在对象的List中,则在下一个会话开始时数据仍将存在。此外,我需要所有客户端共享相同的控制器及其拥有的数据,即单例。
除了制作所有成员static
,这是一个糟糕的解决方案,我该如何实现?
答案 0 :(得分:2)
您可以使用HttpRuntime.Cache或Singleton。
所有客户共享同一个控制器及其拥有的数据
HttpRuntime.Cache 是该方案的不错选择。
请注意,当AppDomain回收或应用程序崩溃时,缓存将清除。
在Cache中存储数据与Cache和Singleton基本相同。
但是,Cache具有额外的功能 - 例如Web Farm和Web Garden中的过期和分布式缓存。
public class Singleton
{
static Singleton()
{
allSingletons = new Dictionary<Type, object>();
}
static readonly IDictionary<Type, object> allSingletons;
public static IDictionary<Type, object> AllSingletons
{
get { return allSingletons; }
}
}
public class Singleton<T> : Singleton
{
static T instance;
public static T Instance
{
get { return instance; }
set
{
instance = value;
AllSingletons[typeof(T)] = value;
}
}
}
// Usage
Singleton<IList<string>>.Instance = new List<string> { "One", "Two", "Three" };
IList<string> collection = Singleton<IList<string>>.Instance;
答案 1 :(得分:1)
如果您有跨会话的多个请求可用的数据列表,请使用某种中央存储库来存储它。这可以是数据库或缓存,甚至是单例对象。如果对象是运行时对象(即,将其存储在缓存中而不是数据库中),则不要直接使用单例或HttpRuntime.Cache - 实现某种ICache
接口并在代码的其余部分中使用它,因此您不必在代码中对代码进行硬编码。
例如:
public interface ICache
{
void Add ( string cacheKey, object itemToAdd, TimeSpan itemLifeTime );
object Get ( string cacheKey );
object Remove ( string cacheKey );
}
这是一个非常简单的界面,仅用于示例;在生产代码中,您希望通过更好的类型支持,更多选项等对其进行更精细的调整。但是,它必须足够简单,以便您可以轻松地在其后面交换可能不兼容的实现。
完成此操作后,您可以根据需要创建多个缓存实现,并在运行时加载所需的缓存实现。例如,一个特定的实现可以使用Cache
,只要数据仅在单个服务器上需要(Cache
是本地的,因此服务器场上的多个服务器不共享高速缓冲存储器)。
public class LocalCache : ICache
{
public void Add ( string cacheKey, object itemToAdd, TimeSpan itemLifeTime )
{
HttpRuntime.Cache.Add ( ... );
}
public object Get ( string cacheKey )
{
return ( HttpRuntime.Cache.Get ( ... ) );
}
public object Remove ( string cacheKey )
{
return ( HttpRuntime.Cache.Remove ( ... ) );
}
}
这将为您提供本地缓存的实现。如果稍后您需要分布式缓存,则可以轻松创建与分布式缓存对话的新实现(Couchbase是一种可能性,但还有其他可能)。
实现之后,您可以使用IoC库(如LightInject或其他)来实例化您想要的特定实现,这样您就可以避免对代码中的特定类型进行硬编码。
正如您所看到的,LocalCache
本身不是一个单独的(它确实委托给一个,因为缓存的重点在于它可以集中访问,但这是隐藏的实现细节。实现将以不同的方式访问缓存,但接口是相同的,您的应用程序将不知道更改。)