ABP框架应用领域层

应用层

•应用服务

•数据传输对像(DTO)

•验证DTO

•授权(权限验证)

领域服务(或DDD中的服务)用于执行领域操作和业务规则。Eric Evans描述了一个好的服务应该具备下面三个特征:

1.和领域概念相关的操作不是一个实体或者值对象的本质部分。

2.接口定义在领域模型其他元素的条款中。

3.操作是无状态的。

跟获得或返回一个数据传输对象的应用服务方法(DTO)不同,领域服务获得或者返回一个领域对象(比如实体或值类型)。

一个领域服务可以用于应用服务,也可以用于其他的领域服务,但不能直接用于展现层,服务层才直接用于展现层。

应用服务的定义

•应用服务用于将领域逻辑暴露给展现层。展现层调用具有DTO参数的应用服务,使用领域对象来执行一些特定的业务逻辑并返回给展现层一个DTO。这样,展现层就完全独立于领域层了。

•在一个理想的分层应用中,展现层永远不直接和领域对象打交道。

IApplicationService接口和ApplicationService类

1.ABP定义了IApplicationService接口,所有的应用服务按照惯例实现了该接口。当实现时,领域服务会以transient自动注册到依赖注入系统。

2.此外,领域服务(可选地)可以从ApplicationService类继承。因此,它可以使用一些继承的属性,比如AbpSession,Logger等等。如果没有继承,如果需要的话也可以注入这些属性。

讨论:

为什么不使用应用服务实现领域服务中的逻辑呢?

我们可以简单地说,它不是应用服务要干的活。因为领域逻辑不是一个用例(use-case),而是一个 业务操作。我们可以在不同的用例中使用相同的“将一个任务派给一个人”的逻辑。比如说我们以后会更新这个任务,并且将这个任务派给其他人。

因此,我们可以使用相同的领域逻辑,这个逻辑就是“将一个任务派给一个人”,我们不用考虑这个具体的人和具体的任务。此外,我们可能有两个不同的UI(一个移动端应用和一个web应用)来共享相同的领域。

DTO用于应用层和展现层间的数据传输。

展现层调用具有DTO参数的应用服务方法,然后应用服务使用领域对象来执行一些特定的业务逻辑,最后返回给展现层一个DTO。

因此,展现层完全独立于领域层。在一个理想的分层应用中,展现层不直接和领域对象打交道(仓储,实体...)。

为何需要DTO

为每个应用服务方法创建一个DTO起初可能被看作是一项乏味而又耗时的事情。但如果正确地使用它,那么DTOs可能会拯救你应用。为啥呢?

•领域层抽象

DTO为展现层抽象领域对象提供了一种有效方式。这样,层与层之间就正确分离了。即使你想完全分离展现层,仍然可以使用已存在的应用层和领域层。相反,只要领域服务的契约(方法签名和DTOs)保持不变,即使重写领域层,完全改变数据库模式,实体和ORM框架,也不需要在展现层做任何改变。

•数据隐藏

试想你有一个User实体,包含Id,Name,EmailAddress和Password字段。如果UserAppService的GetAllUsers()方法返回一个List,即使你没有在屏幕上显示它,那么任何人也都能看到所有user的密码。它不是涉及安全的,而是与数据隐藏相关的。应用服务都应该返回给展现层需要的,不要更多,也不很少,要的是恰到好处。

•序列化和懒加载问题

ORM框架延迟加载、实体相互引用...

DTO惯例和验证

为每个应用服务方法创建一个DTO起初可能被看作是一项乏味而又耗时的事情。但如果正确地使用它,那么DTOs可能会拯救你应用。为啥呢?

一个唯一的权限是为需要授权的每个操作定义的。我们应该在使用权限之前定义一个权限。ABP的设计是模块化的,因此不同的模块可以有不同的权限。为了定义模块的权限,应该创建一个派生自AuthorizationProvider(以下翻译为授权提供者)的类。

一个权限定义了一些属性:

•Name:系统中 唯一的 名字。最好为权限的名字定义一个const字符串而不是变量字符串。我们偏向使用“.”符号用于有层次的名字,但这不是强制的。你可以设置任何你喜欢的名字,唯一的一点是保证它必须是唯一的。

•DisplayName:用于以后在UI上显示权限的本地化字符串。

•Description:用于以后在UI上显示权限定义的本地化字符串。

•IsGrantedByDefault:表示该权限是否授予给所有登录的用户,除非该权限显式禁止未授予给用户。该值一般默认为false。

•MultiTenancySides:对于多租户应用,租户或者租主可以使用同一个权限。这是一个Flags枚举,因此一个权限可以用于租户和租主。

•DependedFeature:可以用于声明一个功能的依赖。因此,只有功能依赖满足了,该权限才会被授予。

一个权限可以有父权限和子权限。虽然这不会影响权限检查,但是在UI上组合权限有所帮助。

检查权限:AbpAuthorize(MVC控制器是AbpMvcAuthorize,Web API控制器是AbpApiAuthorize)是最简单也是最普通的检查权限的方式。

AbpAuthorize特性需要注意的地方

ABP对于授权使用了强大的动态方法拦截AOP(interception)。因此,使用AbpAuthorize特性有一些约定:

•不能用于私有方法。

•不能用于静态方法。

•不能用于非注入类的方法(我们必须要使用依赖注入)。

•可以用于任何 public方法,如果该方法是通过接口调用的(比如应用服务通过接口使用)。

•方法应该是virtual的,如果它是从类的引用直接调用的(比如ASP.Net MVC或者Web API的控制器)。

•如果方法是protected的,那么它应该是 virtual的。

回顾

•应用服务:应用服务与领域服务的区别,如何定义一个领域服务

•DTO:DTO的定义、DTO给系统带来的好处、常用的DTO基类

•输入验证:应用层参数验证、自定义验证规则

•授权:定义权限、给应用层接口添加权限、代码中判断权限

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值