有没有办法在Microsoft Enterprise Library中创建多个CacheManager实例,以编程方式不依赖于配置文件

时间:2011-09-14 07:59:27

标签: caching enterprise-library

我们正在尝试迁移以使用Microsoft Enterprise Library - 缓存块。但是,缓存管理器初始化似乎与配置文件条目紧密相关,我们的应用程序即时创建内存“容器”。无论如何,使用预先配置的值集(仅限内存)可以动态实例化缓存管理器的实例。

2 个答案:

答案 0 :(得分:4)

Enterprise Library 5有一个fluent configuration,可以轻松地以编程方式配置块。例如:

var builder = new ConfigurationSourceBuilder();

builder.ConfigureCaching()
       .ForCacheManagerNamed("MyCache")
       .WithOptions
         .UseAsDefaultCache()
         .StoreInIsolatedStorage("MyStore")
         .EncryptUsing.SymmetricEncryptionProviderNamed("MySymmetric");

var configSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(configSource);
EnterpriseLibraryContainer.Current 
  = EnterpriseLibraryContainer.CreateDefaultContainer(configSource);

不幸的是,您似乎需要立即配置整个块,因此您无法动态添加CacheManagers。 (当我在同一个构建器上调用ConfigureCaching()两次时会抛出异常。)您可以创建一个新的ConfigurationSource,但之后会丢失以前的配置。也许有一种方法可以检索现有配置,修改它(例如添加一个新的CacheManager)然后替换它?我找不到办法。

另一种方法是直接使用Caching类。

以下示例使用Caching类来实例化两个CacheManager实例,并将它们存储在静态Dictionary中。不需要配置,因为它没有使用容器。我不确定这是个好主意 - 对我来说感觉有点不对劲。这很简陋,但希望有所帮助。

public static Dictionary<string, CacheManager> caches = new Dictionary<string, CacheManager>();

static void Main(string[] args)
{
    IBackingStore backingStore = new NullBackingStore();
    ICachingInstrumentationProvider instrProv = new CachingInstrumentationProvider("myInstance", false, false,
        new NoPrefixNameFormatter());

    Cache cache = new Cache(backingStore, instrProv);
    BackgroundScheduler bgScheduler = new BackgroundScheduler(new ExpirationTask(null, instrProv), new ScavengerTask(0,
        int.MaxValue, new NullCacheOperation(), instrProv), instrProv);

    CacheManager cacheManager = new CacheManager(cache, bgScheduler, new ExpirationPollTimer(int.MaxValue));
    cacheManager.Add("test1", "value1");
    caches.Add("cache1", cacheManager);

    cacheManager = new CacheManager(new Cache(backingStore, instrProv), bgScheduler, new ExpirationPollTimer(int.MaxValue));
    cacheManager.Add("test2", "value2");            
    caches.Add("cache2", cacheManager);

    Console.WriteLine(caches["cache1"].GetData("test1"));
    Console.WriteLine(caches["cache2"].GetData("test2"));
}

public class NullCacheOperation : ICacheOperations
{
    public int Count { get { return 0; } }
    public Hashtable CurrentCacheState { get { return new System.Collections.Hashtable(); } }
    public void RemoveItemFromCache(string key, CacheItemRemovedReason removalReason) {}
}

如果过期和清理策略相同或许最好创建一个CacheManager,然后使用一些智能密钥名来表示不同的“容器”。例如。密钥名称可以采用“{container name}:{item key}”格式(假设冒号不会出现在容器或密钥名称中)。

答案 1 :(得分:3)

您可以使用UnityContainer:

        IUnityContainer unityContainer = new UnityContainer();
        IContainerConfigurator configurator = new UnityContainerConfigurator(unityContainer);

        configurator.ConfigureCache("MyCache1");

        IContainerConfigurator configurator2 = new UnityContainerConfigurator(unityContainer);
        configurator2.ConfigureCache("MyCache2");

        // here you can access both MyCache1 and MyCache2:
        var cache1 = unityContainer.Resolve<ICacheManager>("MyCache1");
        var cache2 = unityContainer.Resolve<ICacheManager>("MyCache2");

这是IContainerConfigurator的扩展类:

public static void ConfigureCache(this IContainerConfigurator configurator, string configKey)
    {
        ConfigurationSourceBuilder builder = new ConfigurationSourceBuilder();
        DictionaryConfigurationSource configSource = new DictionaryConfigurationSource();
        // simple inmemory cache configuration
        builder.ConfigureCaching().ForCacheManagerNamed(configKey).WithOptions.StoreInMemory();
        builder.UpdateConfigurationWithReplace(configSource);
        EnterpriseLibraryContainer.ConfigureContainer(configurator, configSource);
    }

使用此方法,您应该管理静态IUnityContainer对象,并可以添加新缓存,以及在任何地方重新配置现有缓存设置。