2016-06-21 879 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

非常感谢你。我很抱歉我一直忙于其他项目,只是有机会尝试这个解决方案。 –