我们正在尝试迁移以使用Microsoft Enterprise Library - 缓存块。但是,缓存管理器初始化似乎与配置文件条目紧密相关,我们的应用程序即时创建内存“容器”。无论如何,使用预先配置的值集(仅限内存)可以动态实例化缓存管理器的实例。
答案 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对象,并可以添加新缓存,以及在任何地方重新配置现有缓存设置。