如何将其他依赖项/配置注入装饰类

时间:2015-03-23 15:16:21

标签: c# .net dependency-injection simple-injector

我有一个IRepository<>和一些Setting实体。我知道对于这个实体,我需要一个缓存的存储库,所以我想创建一个ICachedRepository<Setting>装饰器并用Simple Injector注册它。

问题是我有其他配置需要以某种方式传递到缓存的存储库,例如到期时间跨度,预取政策等

CachedRepository(IRepository repository, CachedRepositoryConfiguration configuration)
{
   ...
}

我该怎么做? (对于不同的存储库,这些配置当然可以是不同的,例如一个30分钟,另一个1小时)

1 个答案:

答案 0 :(得分:1)

Simple Injector不允许您配置装饰器的构造函数值(尽管可以通过implementing a custom IDependencyInjectionBehavior - 或{2}中的IConstructorInjectionBehavior来完成。

最简单的方法是回退属性注入并为每个装饰器注册一个初始化器:

public class CachingRepositoryDecorator<TEntity> : IRepository<TEntity>
{
    private readonly IRepository<TEntity> decoratee;
    public CachingRepositoryDecorator(IRepository<TEntity> decoratee) {
        this.decoratee = decoratee;
        this.Configuration = CachedRepositoryConfiguration.NoCaching;
    }

    public CachedRepositoryConfiguration Configuration { get; set; }

    // IRepository<T> methods here.
}

container.RegisterDecorator(typeof(IRepository<>), 
    typeof(CachingRepositoryDecorator<>));

container.RegisterInitializer<CachingRepositoryDecorator<Setting>>(decorator => {
   decorator.Configuration = 
       CachedRepositoryConfiguration.AbsoluteExpiration(TimeSpan.FromMinutes(30));
});

另一种选择是使用Context Based injection。使用文档中给出的扩展方法,您可以执行以下操作:

public class CachingRepositoryDecorator<TEntity> : IRepository<TEntity>
{
    private readonly IRepository<TEntity> decoratee;
    private readonly CachedRepositoryConfiguration configuration;
    public CachingRepositoryDecorator(IRepository<TEntity> decoratee,
        CachedRepositoryConfiguration configuration) {
        this.decoratee = decoratee;
        this.configuration = configuration;
    }

    // IRepository<T> methods here.
}

container.RegisterDecorator(typeof(IRepository<>), 
    typeof(CachingRepositoryDecorator<>));

container.RegisterWithContext<CachedRepositoryConfiguration>(context => {
    if (context.ImplementationType == typeof(CachingRepositoryDecorator<Setting>)) {
        return CachedRepositoryConfiguration.AbsExpiration(TimeSpan.FromMinutes(30));
    } else {
        CachedRepositoryConfiguration.NoCaching;
    }
});

第三个选项是使配置对象具有通用性,如下所示:

public class CachingRepositoryDecorator<TEntity> : IRepository<TEntity>
{
    private readonly IRepository<TEntity> decoratee;
    private readonly CachedRepositoryConfiguration<TEntity> configuration;
    public CachingRepositoryDecorator(IRepository<TEntity> decoratee,
        CachedRepositoryConfiguration<TEntity> configuration) {
        this.decoratee = decoratee;
        this.configuration = configuration;
    }

    // IRepository<T> methods here.
}

container.RegisterDecorator(typeof(IRepository<>), 
    typeof(CachingRepositoryDecorator<>));

container.RegisterSingleton<CachedRepositoryConfiguration<Setting>>(
    CachedRepositoryConfiguration<Setting>.Absolute(TimeSpan.FromMinutes(30)));

container.RegisterSingleton<CachedRepositoryConfiguration<Customer>>(
    CachedRepositoryConfiguration<Customer>.Sliding(TimeSpan.FromMinutes(5)));

// Register the 'no caching' configuration as fallback
container.Register(
    typeof(CachedRepositoryConfiguration<>),
    typeof(NoCachingCachedRepositoryConfiguration<>).
    Lifestyle.Singleton);

public sealed class NoCachingCachedRepositoryConfiguration<T>
    : CachedRepositoryConfiguration<T>
{
    public NoCachingCachedRepositoryConfiguration() : base(cache: false) { }
}

此第三个选项允许您完全删除条件注册。