繁体   English   中英

使用Generic复杂类型和AutoFac注册通用类型

[英]Registering Generic Types using Generic complex type with AutoFac

我有一个缓存存储库,它继承自与我的数据存储库相同的接口。

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

缓存存储库在其构造函数中引入与其泛型类型匹配的IReadOnlyRepository。 有了这个,我能够实现代码,检查项目是否在缓存中,如果没有从数据库检索并存储到缓存。 我遇到了在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();
        }
}

谢谢!

我想你想要的是一个装饰设计模式的实现。 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");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM