我有一个抽象了文件IO加载我IAppSettingsLoader
文件的app.config
接口。
public interface IAppSettingsLoader
{
IEnumerable<KeyValuePair<string, string>> LoadAppSettings();
}
我有一个加载实际文件中的类:
public class FileAppSettignsLoader : IAppSettingsLoader
{
public IEnumerable<KeyValuePair<string, string>> LoadAppSettings()
{
// Perform actual loading through ConfigurationManager.AppSettings
}
}
然后,我有试图监视文件更改app.config
缓存装饰
public class CachedAppSettingsLoader : IAppSettingsLoader
{
private readonly ObjectCache _cache;
private readonly string _cacheKey;
private readonly CacheItemPolicy _cacheItemPolicy;
private readonly IAppSettingsLoader _innerAppSettingsLoader;
public CachedAppSettingsLoader(ObjectCache cache,
string cacheKey,
CacheItemPolicy cacheItemPolicy,
IAppSettingsLoader innerAppSettingsLoader)
{
_cacheKey = cacheKey;
_cacheItemPolicy = cacheItemPolicy;
_cache = cache;
_innerAppSettingsLoader = innerAppSettingsLoader;
}
public IEnumerable<KeyValuePair<string, string>> LoadAppSettings()
{
object cached = _cache[_cacheKey];
if (cached != null)
{
return (IEnumerable<KeyValuePair<string, string>>)cached;
}
var keyValuePairs = _innerAppSettingsLoader.LoadAppSettings();
// _cacheItemPolicy will contain a HostFileChangeMonitor
_cache.Add(_cacheKey, keyValuePairs, _cacheItemPolicy);
return keyValuePairs;
}
}
我试图注册没有成功的简单注射器这种缓存装饰。这是我的尝试:
private void RegisterDependencies(Container container)
{
container.RegisterSingleton(() =>
ResolveCachedAppSettingsLoader(container));
container.Register<IAppSettingsLoader, FileAppSettingsLoader>(
Lifestyle.Singleton);
container.RegisterDecorator<IAppSettingsLoader, CachedAppSettingsLoader>(
Lifestyle.Singleton);
}
private CachedAppSettingsLoader ResolveCachedAppSettingsLoader(Container container)
{
var cacheItemPolicy = new CacheItemPolicy();
cacheItemPolicy.ChangeMonitors.Add(new HostFileChangeMonitor(new[] { "app.config" }));
var innerAppSettingsLoader = container.GetInstance<IAppSettingsLoader>();
return new CachedAppSettingsLoader(
"AuthorizationRecords",
cacheItemPolicy,
MemoryCache.Default,
innerAppSettingsLoader);
}
失败的原因是简单的注射器没有认识到我的自定义ResolveCachedAppSettingsLoader
作为一个实例工厂CachedAppSettingsLoader
。
型CachedAppSettingsLoader的构造包含不能被用于构造子注入String类型的参数“cacheKey”。参数名:decoratorType
我的问题是如何能够提供一个定制Func<CachedAppSettingsLoader>
在简单的喷油器来构建这个缓存装饰(与依赖关系)?
简单的喷油器不容易允许注册包含原始配置值装饰。有多种方式来扩展简单的喷油器,使这样的行为,但我要说的是,有更容易的解决方案。
除了扩展简单喷油器,你基本上有两个选择这里。要么你回退到对象图的这一部分的结构手册,或者提取组原始配置值到它自己的配置对象,它可以作为在容器中单寄存器。
您可以手动构建装饰和decoratee如下:
container.RegisterSingleton<IAppSettingsLoader>(
new CachedAppSettingsLoader(
"AuthorizationRecords",
cacheItemPolicy,
MemoryCache.Default,
new FileAppSettingsLoader()));
另一种选择是提取配置值到自己的类,这可能是个好主意呢:
public class CachedAppSettingsLoaderSettings
{
public ObjectCache Cache;
public CacheItemPolicy Policy;
public string CacheKey;
}
public class CachedAppSettingsLoader : IAppSettingsLoader
{
private readonly CachedAppSettingsLoaderSettings settings;
private readonly IAppSettingsLoader decoratee;
public CachedAppSettingsLoader(
CachedAppSettingsLoaderSettings settings, IAppSettingsLoader decoratee)
{
...
}
}
这个重构后,可以按如下所示注册你的类型:
container.Register<IAppSettingsLoader, FileAppSettingsLoader>(Lifestyle.Singleton);
container.RegisterDecorator<IAppSettingsLoader, CachedAppSettingsLoader>(
Lifestyle.Singleton);
container.RegisterInstance(new CachedAppSettingsLoaderSettings
{
Cache = MemoryCache.Default,
Policy = new CacheItemPolicy { ... },
CacheKey = "AuthorizationRecords"
});