I have an IAppSettingsLoader
interface that abstracts away the file IO for loading my app.config
file.
public interface IAppSettingsLoader
{
IEnumerable<KeyValuePair<string, string>> LoadAppSettings();
}
I have a class that loads the actual file:
public class FileAppSettignsLoader : IAppSettingsLoader
{
public IEnumerable<KeyValuePair<string, string>> LoadAppSettings()
{
// Perform actual loading through ConfigurationManager.AppSettings
}
}
Then I have a caching decorator that tries to monitor file changes to 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;
}
}
I was trying to register this caching decorator with Simple Injector without success. This is what I tried:
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);
}
This fails because Simple Injector fails to recognise my custom ResolveCachedAppSettingsLoader
as an instance factory to CachedAppSettingsLoader
.
The constructor of type CachedAppSettingsLoader contains parameter 'cacheKey' of type String which can not be used for constructor injection. Parameter name: decoratorType
My question is how can I supply a custom Func<CachedAppSettingsLoader>
to construct this caching decorator (with dependencies) in Simple Injector?