c#-在Simple Injector中注册具有原始配置依赖项的装饰器
作者:互联网
我有一个IAppSettingsLoader接口,该接口抽象了文件IO以加载我的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;
}
}
我试图向Simple Injector注册此缓存装饰器,但未成功.这是我尝试的:
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);
}
之所以失败,是因为Simple Injector无法将我的自定义ResolveCachedAppSettingsLoader识别为CachedAppSettingsLoader的实例工厂.
The constructor of type CachedAppSettingsLoader contains parameter
‘cacheKey’ of type String which can not be used for constructor
injection. Parameter name: decoratorType
我的问题是如何提供自定义的Func< CachedAppSettingsLoader>在Simple Injector中构造此缓存装饰器(具有依赖项)?
解决方法:
简单注入器不容易允许注册包含原始配置值的装饰器.有多种方法可以扩展Simple Injector来实现这种行为,但是我想说有更简单的解决方案.
除了扩展Simple Injector之外,这里基本上有两个选择.您可以退一步来手动构建对象图的这一部分,或者将原始配置值组提取到其自己的配置对象中,您可以将其注册为容器中的单例.
您可以手动构造装饰器及其被装饰者,如下所示:
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"
});
标签:dependency-injection,c,net,simple-injector 来源: https://codeday.me/bug/20191026/1934842.html