You can achieve the desired result with an open common implementation and override the default values ββas needed. That is, you define an open shared implementation of CachePolicy<TQuery> ICachePolicy<TQuery> and use the RegisterInitializer method to override the default implementation parts.
Given these definitions:
public interface ICachePolicy<TQuery> { DateTime AbsoluteExpiration { get; } } public class CachePolicy<TQuery> : ICachePolicy<TQuery> { public CachePolicy() { AbsoluteExpiration = Cache.NoAbsoluteExpiration; } public DateTime AbsoluteExpiration { get; set; } } public interface IQueryHandler<TQuery, TResult> { } public class QueryHandlerA : IQueryHandler<A, AResult> { } public class QueryHandlerB : IQueryHandler<B, BResult> { } public sealed class CachingQueryHandlerDecorator<TQuery, TResult> : IQueryHandler<TQuery, TResult> { private readonly IQueryHandler<TQuery, TResult> decorated; public readonly ICachePolicy<TQuery> Policy; public CachingQueryHandlerDecorator( IQueryHandler<TQuery, TResult> decorated, ICachePolicy<TQuery> cachePolicy) { this.decorated = decorated; this.Policy = cachePolicy; } }
Configure the container using the RegisterOpenGeneric method and configure the default values ββusing RegisterInitializer :
public Container ConfigureContainer() { Container container = new Container(); container.RegisterOpenGeneric( typeof(ICachePolicy<>), typeof(CachePolicy<>), Lifestyle.Singleton); container.RegisterInitializer<CachePolicy<A>>(a => a.AbsoluteExpiration = DateTime.Now.AddMinutes(1)); container.RegisterManyForOpenGeneric( typeof(IQueryHandler<,>), typeof(IQueryHandler<,>).Assembly); container.RegisterDecorator( typeof(IQueryHandler<,>), typeof(CachingQueryHandlerDecorator<,>)); container.Verify(); return container; }
These tests demonstrate the result as expected:
[Test] public void GetInstance_A_HasCustomAbsoluteExpiration() { Container container = ConfigureContainer(); var a = container.GetInstance<IQueryHandler<A, AResult>>(); Assert.AreNotEqual( (a as CachingQueryHandlerDecorator<A, AResult>).Policy.AbsoluteExpiration, Cache.NoAbsoluteExpiration); } [Test] public void GetInstance_B_HasDefaultAbsoluteExpiration() { Container container = ConfigureContainer(); var b = container.GetInstance<IQueryHandler<B, BResult>>(); Assert.AreEqual( (b as CachingQueryHandlerDecorator<B, BResult>).Policy.AbsoluteExpiration, Cache.NoAbsoluteExpiration); }
source share