2017-02-23 42 views
3

我有一个IAppSettingsLoader接口,它抽象出用于加载我的app.config文件的文件IO。在Simple Injector中注册具有原始配置依赖关系的修饰器

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>在简单的喷油器构建这个缓存​​装饰(与依赖关系)?

回答

2

Simple Injector不容易注册包含原始配置值的修饰符。有多种方法可以扩展Simple Injector来实现这种行为,但我会说有更简单的解决方案。

除了扩展简单注射器,你基本上有两个选择。您可以回退到手动构建对象图的这一部分,或者将原始配置值组提取到它自己的配置对象中,您可以在容器中注册为单例配置对象。

您可以手动构建装饰和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.RegisterSingleton(new CachedAppSettingsLoaderSettings 
{ 
    Cache = MemoryCache.Default, 
    Policy = new CacheItemPolicy { ... }, 
    CacheKey = "AuthorizationRecords" 
}); 
+0

我是b基本上和你的第一个解决方案做同样的事情:)但你的第二个解决方案对我更有意义,顺便尝试一下 – rexcfnghk

+0

,如果我使用你的第一个选项,HostFileChangeMonitor实例会在它熄灭时自动处理范围? – rexcfnghk

+0

在任何情况下都不会由Simple Injector处理。它对此一无所知。 – Steven