2016-06-21 887 views
1

我有一個從我的數據存儲庫繼承的相同接口的Caching Repository。使用AutoFac使用泛型複雜類型註冊泛型

public interface IReadOnlyRepository<T,U> 
{ 
    T Get(U key); 
    IList<T> GetAll(); 
} 

高速緩存存儲庫在其構造函數中接受一個I​​ReadOnlyRepository,它與其泛型類型相匹配。有了這個,我能夠實現檢查項目是否在緩存中的代碼,如果沒有從數據庫中檢索並存儲到緩存。我遇到了在AutoFac中註冊此通用緩存的問題。我有以下的代碼被打破,現在

builder.RegisterGeneric(typeof(DomainObjectRepository<,>)).Keyed("iRepoLayer",typeof(IRepository<,>)); 
builder.RegisterGeneric(typeof(CacheRepo<,>)) 
    .As(typeof(IRepository<,>)) 
    .WithParameters(new List<Parameter>() 
    { 
     new ResolvedParameter(
      (pi, ctx) => pi.ParameterType == typeof(IRepository<,>), 
      (pi, ctx) => ctx.ResolveKeyed("iRepoLayer",typeof(IRepository<,>))), 
      ...(Other Constructor params) 
    } 

接口

public interface IReadOnlyRepository<T,U> 
    { 
     /// <summary> 
     /// Gets the specified item from the repository. 
     /// </summary> 
     /// <param name="key"></param> 
     /// <returns></returns> 
     T Get(U key); 

     /// <summary> 
     /// Gets all items in the repository 
     /// </summary> 
     /// <returns></returns> 
     IList<T> GetAll(); 
    } 

數據層實現

public class ReadOnlyRepository<T,U> :IReadOnlyRepository<T,U> where T:ObjectWithId<U> 
    { 
     internal ICoreRepository _coreRepository; 

     public ReadOnlyRepository(ICoreRepository coreRepository) 
     { 
      _coreRepository = coreRepository; 
     } 

     private static Expression<Func<T, object>> _getId = t => t.Id; 

     public T Get(U key) 
     { 
      return _coreRepository.GetBy(_getId, key); 
     } 

     public virtual IList<T> GetAll() 
     { 
      return _coreRepository.GetAll<T>().ToList(); 
     } 
} 

緩存層

public class CacheReadOnlyRepo<T,TId> : IReadOnlyRepository<T, TId> where T :ObjectWithId<TId> 
    { 
     private IReadOnlyRepository<T, TId> _readOnlyRepo { get; set; } 
     protected static readonly string IdKeyPrefix = GetKeyPrefix(o => o.Id); 
     protected static readonly string GetAllKey = GetSetCacheKey<T>(); 
     protected ICoreCachingRepo _coreCachingRepo; 

     public CacheReadOnlyRepo(IReadOnlyRepository<T,TId> readOnlyRepo, CacheEventManager cacheEventManager, ICacheClient cacheClient, ICoreCachingRepo coreCachingRepo) 
     { 
      _readOnlyRepo = readOnlyRepo; 
      _cacheEventManager = cacheEventManager; 
      _cacheClient = cacheClient; 
      _coreCachingRepo = coreCachingRepo; 
     } 

     public T Get(TId id) 
     { 
      var key = GetCacheKey(IdKeyPrefix, id); 
//calls the cache for item and passes method to retreive items if they are not in cache 
      return _coreCachingRepo.GetViaCache(_readOnlyRepo.Get, key, id); 
     } 


     public virtual IList<T> GetAll() 
     { 

      //calls the cache for item and passes method to retreive items if they are not in cache 
      return _coreCachingRepo.GetAllViaCache(_readOnlyRepo.GetAll, GetAllKey).ToList(); 
     } 
} 

謝謝!

+0

你能分享你正在嘗試註冊和依賴什麼接口和類繼承實現(構造函數參數)? –

回答

2

我想你想要的是一個裝飾設計模式的實現。 Autofac明確支持該模式。

這裏是沒有詳細的支持文章:http://nblumhardt.com/2011/01/decorator-support-in-autofac-2-4/

相關代碼段調整爲使用類:

builder.RegisterGeneric(typeof(ReadOnlyRepository<,>)) 
    .Named("read-only-repo", typeof(IReadOnlyRepository<,>)); 

// Register the generic decorator so it can wrap 
// the resolved named generics. 
builder.RegisterGenericDecorator(
    typeof(CacheReadOnlyRepo<,>), 
    typeof(IReadOnlyRepo<,>), 
    fromKey: "read-only-repo"); 
+0

非常感謝你。我很抱歉我一直忙於其他項目,只是有機會嘗試這個解決方案。 –