如何让控制器对象在会话之间存活?

时间:2015-01-12 22:15:09

标签: asp.net .net service asp.net-web-api

我需要我的控制器在会话之间存储数据。因此,如果在会话期间将数据保存在对象的List中,则在下一个会话开始时数据仍将存在。此外,我需要所有客户端共享相同的控制器及其拥有的数据,即单例。

除了制作所有成员static,这是一个糟糕的解决方案,我该如何实现?

2 个答案:

答案 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本身不是一个单独的(它确实委托给一个,因为缓存的重点在于它可以集中访问,但这是隐藏的实现细节。实现将以不同的方式访问缓存,但接口是相同的,您的应用程序将不知道更改。)