我有一個應用程序query/handler based architecture。我有以下接口:基於泛型類型約束在Autofac中有條件地應用通用裝飾器
public interface IQueryHandler<TQuery, TResult> where TQuery : IQuery<TResult>
{
TResult Handle(TQuery query);
}
該接口有許多非通用實現。那些實現被通用裝飾器封裝,以用於日誌記錄,分析,授權等。但是,有時候,我想根據裝飾器的泛型類型約束來有條件地應用泛型裝飾器。就拿只能被應用到返回的查詢,這個緩存裝飾一ReadOnlyCollection<T>
(僅僅是因爲緩存任何的集合,是可變的並沒有太大的意義):
public class CachingQueryHandlerDecorator<TQuery, TResult>
: IQueryHandler<TQuery, ReadOnlyCollection<TResult>>
where TQuery : IQuery<ReadOnlyCollection<TResult>>
{
private readonly IQueryHandler<TQuery, ReadOnlyCollection<TResult>> decoratee;
private readonly IQueryCache cache;
public CachingQueryHandlerDecorator(
IQueryHandler<TQuery, ReadOnlyCollection<TResult>> decoratee,
IQueryCache cache)
{
this.decoratee = decoratee;
this.cache = cache;
}
public ReadOnlyCollection<TResult> Handle(TQuery query)
{
ReadOnlyCollection<TResult> result;
if (!this.cache.TryGetResult(query, out result))
{
this.cache.Store(query, result = this.decoratee.Handle(query));
}
return result;
}
}
什麼可能使它更棘手的是,那些條件裝飾器可以在裝飾器鏈中的任何地方。他們常常是中間的裝飾者之一。例如,這個CachingQueryHandlerDecorator
包裝了一個無條件的ProfilingQueryHandlerDecorator
,並且應該被條件SecurityQueryHandlerDecorator
包裝。
我發現this answer是指有條件地應用非泛型裝飾器;而不是基於泛型類型約束條件應用泛型裝飾器。我們如何使用Autofac中的通用裝飾器來實現這一點?
可能的重複[在基於配置值的Autofac中有條件地應用通用裝飾器](http://stackoverflow.com/questions/23472611/applying-generic-decorators-conditional-in-autofac-based-on-configuration-valu ) –
@JimBolla:這不是重複的IMO。雖然兩者都是有條件地處理泛型裝飾器,但這個問題明確地涉及泛型類型約束,它很可能需要一種不同的方式來處理它們。 – Steven
答案將完全相同......實施與原始問題中推薦的類似的IRegistrationSource。唯一的區別將在'if'語句中。哎呀,你可以爲這個問題做出實現,另一個共享一個通用的抽象基類。 –