VictorTzeng / Zxw.Framework.NetCore

基于EF Core的Code First模式的DotNetCore快速开发框架,其中包括DBContext、IOC组件autofac和AspectCore.Injector、代码生成器(也支持DB First)、基于AspectCore的memcache和Redis缓存组件,以及基于ICanPay的支付库和一些日常用的方法和扩展,比如批量插入、更新、删除以及触发器支持,当然还有demo。欢迎提交各种建议、意见和pr~

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

觉得在service层中调用自定义repository感觉不合理

liuyl1992 opened this issue · comments

commented

在业务service:TutorClassTypeService中调用数据层ITutorClassTypeRepository中感觉多此一举。
为何不在service中直接调用IRepository泛型,免去每次都要为业务写一层业务层还要再多一层数据层ITutorClassTypeRepository

commented

谢谢,在dev分支里已经移除了service层,请参考dev分支

commented

但是我依旧觉得在一个业务类中构造函数注入需要的操作表的BaseRepository(),在这个业务类中调用对应BaseRepository的curd用起来会更方便顺手

commented

类似这样用法会更清晰吧
public class ProductService : IProductService
{
private readonly IBaseRepository<Entity1,identity> _baseRepository1;
private readonly IBaseRepository<Entity2,identity> _baseRepository2;

    public ProductService(IBaseRepository<Entity1,identity>  baseRepository1,
                                     IBaseRepository<Entity1,identity>  baseRepository2 )
    {
        _baseRepository1= baseRepository1;
         _baseRepository2=baseRepository2;
    }

     public void Test()
   {
          _baseRepository1.Find(...);
          _baseRepository2.Find(...);
    }

}

commented

对我个人而言,Base里面封装的都是共用方法,毕竟每个Repository都有自己的业务功能。

commented

可是那些公用方法都作用于泛型指定的单张表,BaseRepository之外的表还是要构造函数注入一遍

commented

在项目里,BaseRepository是抽象类,主要是封装些共用方法,每个Repository都继承自BaseRepository,且都有对应的接口类。在demo里面注册至容器的时候过滤掉了抽象类,在Service里通过构造函数注入需要用到的IRepository就好。
public class SysMenuRepository : BaseRepository<SysMenu, Int32>, ISysMenuRepository

public SysMenuController(ISysMenuRepository menuRepository) { this.menuRepository = menuRepository ?? throw new ArgumentNullException(nameof(menuRepository)); }

commented

数据仓储你这样也是一种实现,每个表的操作要单独写一个Repository,service中去调。不过感觉这里的Repository如果可以不写,在service中直接调用BaseRepository的curd操作会更简化,就像上面贴的那种使用:

public class ProductService : IProductService
{
private readonly IBaseRepository<Entity1,identity> _baseRepository1;
private readonly IBaseRepository<Entity2,identity> _baseRepository2;

public ProductService(IBaseRepository<Entity1,identity>  baseRepository1,
                                 IBaseRepository<Entity1,identity>  baseRepository2 )
{
    _baseRepository1= baseRepository1;
     _baseRepository2=baseRepository2;
}

 public void Test()

{
_baseRepository1.Find(...);//这里的find是BaseRepository中的find
_baseRepository2.Find(...);//这里的find是BaseRepository中的find
}
}

commented

谢谢,我参考参考

commented

还有个建议:你把SaveChanges封装在curd中,写死不好吧,如果统一事务的话只能外面using包一下,所以建议SaveChanges由用户自己控制比较好。一般数据仓储取集合Tolist由用户控制比较好吧

commented

缓存问题:如果用户不小心其他地方的key值和你那个特性中设置的默认一样不就覆盖了吗,key值是不是由用户确定,并放在一个枚举列表中或者const中集中管理会比较好,其他地方如果更改了数据库的值,拿什么key去清除缓存的值呢(业务人员往往明确key值,就知道操作哪一个kay,不然你底层可能是表名加其他值组合的key,翻源码才能明确)

commented

缓存问题:缓存key默认是根据方法名和传递的参数来生成的,可以参考CacheKey.cs,现在可以把cachekey传入。
image
[RedisCache(CacheKey = "Redis_Cache_SysMenu", Expiration = 5)]
IList<SysMenu> GetMenusByCache(Expression<Func<SysMenu, bool>> where);