2016-06-21 10 views
1

私のデータリポジトリと同じインターフェイスから継承するキャッシングリポジトリがあります。AutoFacで汎用複合型を使用して汎用タイプを登録する

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

キャッシングリポジトリは、ジェネリック型と一致するIReadOnlyRepositoryをコンストラクタにとります。これで、アイテムがキャッシュにあるかどうかを確認するコードを実装できます。データベースから取り出してキャッシュに格納しない場合は、コードを実装できます。私はAutoFacでこのGeneric Cacheの登録に問題があります。私は

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

ありがとう。私は他のプロジェクトに忙しかったので、このソリューションを試してみるしかありません。 –

関連する問題