我一直在研究装饰器设计模式(我是设计模式的新手)。
我已经在使用baseerepository模式。但是我也想使用一些缓存
下面的示例只是一个转储示例。
所以我有genericrepository接口及其实现
public interface IGenericRepository<T> where T : class
{
T GetById(int id);
IEnumerable<T> GetAll();
Task<T> GetByIdAsync(int id);
T Add(T entity);
void AddRange(IEnumerable<T> entities);
Task<T> AddAsync(T entity);
Task AddRangeAsync(IEnumerable<T> entities);
void Remove(T entity);
void RemoveRange(IEnumerable<T> entities);
int SaveChanges();
Task<int> SaveChangesAsync();
}
然后我创建了一个自定义存储库,例如IBlogRepositorypublic interface IBlogRepository : IBaseRepository<Blog>
{
public Task<Blog> GetBlogsByCreatorAsync(int creatorId);
}
与BlogRepository的实现
public class BlogRepository : BaseRepository<Blog>, IBlogRepository
{
public BlogRepository(DbContext db) : base(db)
{
}
public Task<Blog> GetBlogsByCreatorAsync(int creatorId) =>
db.Blogs.Where(b => b.CreatorId == creatorId)
.ToListAsync();
}
我觉得这很酷,然后我意识到我需要提高我的"速度"。我开始使用IMemoryCache,但在仓库代码如下。
public class BlogRepository : BaseRepository<Blog>, IBlogRepository
{
public BlogRepository(DbContext db, IMemoryCache cache) : base(db)
{
}
public Task<Blog> GetBlogsByCreatorAsync(int creatorId)
{
// if in cache else go to db
}
}
然后我遇到了装饰图案,我想为什么不呢,我开始使用它,但我现在很挣扎。我创建了CachedBlogRepository也就是实现IBlogRepository,但当我要求VS实现所有接口方法…
public class CachedBlogRepository : IBlogRepository
{
//All BaseRepository methods appeared here...
//But I want cache only the GetBlogsByCreatorAsync method
}
那么这里的最佳实践是什么呢?是我遗漏了什么还是我做错了什么?
看起来这是一个可以使用CachedRepository模式的地方。
我强烈建议你阅读这篇关于在asp.net Core中构建cacherepository的漂亮文章
所以在应用CachedRepository模式之后会是这样的:
public List<Blog> GetBlogsByCreatorAsync(int id)
{
string key = MyModelCacheKey + "-" + id;
return _cache.GetOrCreate(key, entry =>
{
entry.SetOptions(cacheOptions);
return _repository.GetBlogsByCreatorAsync(id);
});
}
你可以在gihub
看到源代码首先我不明白这部分:
BlogRepository: BaseRepository, bloblogrepository
应该是:
BlogRepository: bloblogrepository ?
现在,当它出现在Decorator Pattern时,我会这样做:
public interface IGenericRepository<T> where T : class
{
T GetById(int id);
IEnumerable<T> GetAll();
Task<T> GetByIdAsync(int id);
T Add(T entity);
void AddRange(IEnumerable<T> entities);
Task<T> AddAsync(T entity);
Task AddRangeAsync(IEnumerable<T> entities);
void Remove(T entity);
void RemoveRange(IEnumerable<T> entities);
int SaveChanges();
Task<int> SaveChangesAsync()
}
(组件)
public class BlogRepository : BaseRepository<Blog>, IBlogRepository
{
public BlogRepository(DbContext db) : base(db)
{
}
public Task<Blog> GetBlogsByCreatorAsync(int creatorId) =>
db.Blogs.Where(b => b.CreatorId == creatorId)
.ToListAsync();
}
(具体组件)
abstract class Decorator : IGenericRepository<T>
{
protected IGenerecRepository _repository;
public Decorator( IGenerecRepository repository)
{
this._repository = repository;
}
public override Task<Blog> GetBlogsByCreatorAsync()
{
if (this._repository != null)
{
return this._repository.GetBlogsByCreatorAsync();
}
else
{
return string.Empty;
}
}
}
(基地Decorator)
class CacheDecorator : Decorator
{
public CacheDecorator(IGenericRepository repo) : base(repo)
{
}
public override Task<Blog> GetBlogsByCreatorAsync()
{
//cache behavior
}
}
Uasage:
BlogRepository _basicRepo = new BlogRepository();
CacheDecorator _cacheDecorator = new CacheDecorator(_basicRepo);
_cacheDecorator.GetBlogsByCreatorAsync(creatorId);
Decorator Pattern将行为添加到主基本行为中。它需要一个包装(基本组件)来包装它周围的新行为。