ABP+AdminLTE+Bootstrap Table权限管理系统第四节--仓储,服务,服务接口及依赖注入

ABP+AdminLTE+Bootstrap Table权限管理系统一期
Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMS
前往博客园总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期

在ABP框架中,仓储,服务,这块算是最为重要一块之一了.ABP框架提供了创建和组装模块的基础,一个模块能够依赖于另一个模块,一个程序集可看成一个模块,
一个模块可以通过一个类来定义这个模块,而给定义这个类要继承自已经疯转好的AbpModule..net通过反射来获取这些程序集中的类或者方法
模块的调用往往涉及到先后顺序,如果模块A依赖于模块B,那么模块B要在模块A之前初始化,初始化就相当于注册,如使用IocManager对登记类进行注册,


上面这个方法我们就把MyModule1 注入到MyModule2中了,在调用MyModule2的时候可以初始化MyModule1 .
什么是依赖注入呢?百科是这样说:“依赖注入是一种软件设计模式,一个或多个依赖项(或服务)被注入或通过引用传递到一个依赖对象,并且成为客户端状态的一部分。这种模式把客户端依赖项的创建从它自己的行为中分离出来,允许程序设计成松耦合的,遵循依赖倒置和单一职责的原则。和服务定位器模式相比,它允许客户端知道他们使用的系统查找依赖项。”
不使用依赖注入技术,很难管理依赖项和发布一个结构良好的应用。
假设我们有一个应用程序服务,使用仓储(repository)类插入实体到数据库。在这种情况下,应用程序服务类依赖于仓储(repository)类,如下

UserService使用UserRepository插入Person到数据库。但是这段代码有一些问题:

  1. 服务层UserService通过接口IUserRepository调用CreatePerson实现新增一个User对象,看似调用了IUserRepository接口,但是实际上还是依赖于仓促层的UserRepository.
  2. UserService通过IUserRepository创建对象的时候,实际上new一个UserRepository区实现,这与直接调用UserRepository无差别,IUserRepository失去存在的意义.
  3. 如果未来我们需要修改UserRepository类,但是UserService依赖于它,这时候,我们需要修改所有依赖UserRepository的类.
  4. 有了这样的依赖,很难对UserService进行单元测试。
  5. 与"高内聚低耦合"的的原则背道而驰,这里可以看到服务层与仓储层有依赖.
    为了解决这些问题于是就有了下面这个版本.

    这就是工厂模式,实际上在abp之前我也经常用这种方式,非常繁琐,搭框架老是出错,UserRepositoryFactory是一个静态类,创建并返回一个IUserRepository

UserService服务不需要直接去创建UserRepository.
这种方法虽然可以,但是依然存在一些问题.

  1. UserService依然依赖于UserRepositoryFactory
  2. 每一个仓储都有写一个工厂,很繁琐.
  3. 测试性还是不好.
    解决办法有几种,包括属性注入,构造函数注入,和依赖注入框架等等.


上面就是abp中构造函数注入与属性输入的完美运用.现在,UserService不知道哪些类实现userRepository以及如何创建它。谁需要使用UserService,首先创建一个IUserServiceUserService并将其传递给构造函数就可以了.
有人可能说userRepository的从属类里面可能存在依赖,依赖注入框架自动化管理依赖关系都已经解决了这些问题.构造函数注入模式是一个完美的提供类的依赖关系的方式。通过这种方式,你不能创建类的实例,而不提供依赖项。它也是一个强大的方式显式地声明是什么类的需求正确地工作。
但是,在某些情况下,该类依赖于另一个类,但也可以没有它。这通常是适用于横切关注点(如日志记录)。一个类可以没有工作日志,但它可以写日志如果你提供一个日志对象。在这种情况下,您可以定义依赖为公共属性,而不是让他们放在构造函数,上面例子中NullLogger.Instance 是一个单例对象,实现了ILogger接口,但实际上什么都没做(不写日志。它实现了ILogger实例,且方法体为空),在我们需要写日志的地方,我们只需要UserService.Logger = new Log4NetLogger();如此,我们就可以写入日志了,如果不写就不调用,因此是一个可选的依赖.
几乎所有的依赖注入框架都支持属性注入模式
ABP的依赖注入基于 Castle Windsor框架。Castle Windsor最成熟的DI框架之一。依赖注入的框架还有好多,如Unity,Ninject,StructureMap,Autofac等,之前我用过Unity其他的几个没有研究过,依赖框架都可以自动解决依赖关系。他们可以创建所有依赖项(递归地依赖和依赖关系)。所以你只需要根据注入模式写类和类构造函数&属性,其他的交给DI框架处理!在良好的应用程序中,类甚至独立于DI框架。整个应用程序只会有几行代码或类,显示的与DI框架交互。
有人说上面这个例子看不出来依赖注入啊,其实这里UserService是继承自IUserService,而IUserService继承自IApplicationService,abp在IApplicationService封装了很多东西,ABP会自动注册它,因为它实现IApplicationService接口(它只是一个空的接口)。它会被注册为transient (每次使用都创建实例)。当你注入(使用构造函数注入)IUserService接口成一个类,UserService对象会被自动创建并传递给构造函数。
命名约定在这里非常重要。例如你可以将名字PersonAppService改为 MyPersonAppService或另一个包含“PersonAppService”后缀的名称,由于IPersonAppService包含这个后缀。但是你可以不遵循PeopleService命名您的服务类。如果你这样做,它将不会为IPersonAppService自动注册(它需要自注册(self-registration)到DI框架,而不是接口),所以,如果你想要你应该手动注册它.

仓储

上一章我们已经定义实体类,和DTOs,在仓储中可以直接调用,仓储是在领域层和数据映射层的中介,使用类似集合的接口来存取领域对象.

接口:

实现:

在例子中IRepository继承自abp已经封装好的IRepository<TEntity>中,在IRepository<TEntity>中已经为我们封装好了许多方法,这就省得我们在为每一个仓储创建不同的方法了,这点很好如下图.


包含了各式各样的方法,如增删查改等方法.还有一些Async的异步方法.GetAll返回IQueryable<T>类型的对象。因此我们可以在调用完这个方法之后进行Linq操作.
现在项目中运用的是EF框架,所以如果ORM框架没有提供Async的仓储方法则它会以同步的方式操作。同样地,举例来说,InsertAsync操作起来和EF的新增是一样的,因为EF会直到单元作业(unit of work)完成之后才会写入新实体到数据库中(DbContext.SaveChanges)。
数据库连接的开启和关闭,在仓储方法中,ABP会自动化的进行连接管理.当仓储方法被调用后,数据库连接会自动开启且启动事务。当仓储方法执行结束并且返回以后,所有的实体变化都会被储存, 事务被提交并且数据库连接被关闭,一切都由ABP自动化的控制。如果仓储方法抛出任何类型的异常,事务会自动地回滚并且数据连接会被关闭。上述所有操作在实现了IRepository接口的仓储类所有公开的方法中都可以被调用。如果仓储方法调用其它仓储方法(即便是不同仓储的方法),它们共享同一个连接和事务。连接会由仓储方法调用链最上层的那个仓储方法所管理。
另外所有的仓储对象都是暂时性的。这就是说,它们是在有需要的时候才会被创建。ABP大量的使用依赖注入,当仓储类需要被注入的时候,新的类实体会由注入容器会自动地创建.

返回简书总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期
前往博客园总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354