Есть ли способ создать несколько экземпляров CacheManager в Microsoft Enterprise Library, программно, без зависимости от файла конфигурации - PullRequest
4 голосов
/ 14 сентября 2011

Мы пытаемся перейти на использование Microsoft Enterprise Library - блок кэширования. Однако инициализация менеджера кэша, похоже, довольно сильно связана с записями файла конфигурации, и наше приложение создает «контейнеры» памяти на лету. Есть ли способ, с помощью которого экземпляр диспетчера кэша можно создать на лету, используя предварительно настроенный набор значений (только для памяти).

Ответы [ 2 ]

4 голосов
/ 16 сентября 2011

Enterprise Library 5 имеет плавную конфигурацию , которая упрощает программную настройку блоков. Например:

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);

К сожалению, похоже, вам нужно настроить весь блок сразу, чтобы вы не смогли добавить CacheManager на лету. (Когда я дважды вызываю 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, а затем использовать некоторые интеллектуальные имена ключей для представления различных «контейнеров». Например. имя ключа может иметь формат «{имя контейнера}: {ключ элемента}» (при условии, что двоеточие не будет отображаться в имени контейнера или ключа).

3 голосов
/ 15 ноября 2011

Вы можете использовать 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 и можете добавлять новый кеш,а также перенастроить существующие настройки кэширования в любом месте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...