-
Notifications
You must be signed in to change notification settings - Fork 0
jiaocheng
本仓库为 NuScien 6 平台示例,采用 .NET 6.0 编写,数据库为 Microsoft SQL Server,网络服务部分需要 ASP.NET 6.0 支持。
在开始之前,请用 Microsoft SQL Server Management Studio 连接数据库并打开本仓库 Sql\NuScien.ssmssln 解决方案,然后执行 TablesCreation.sql 文件和 TestTablesCreation.sql 文件,以创建必要的数据库。
通常,我们需要对系统进行分层架构。最基本的形态为 DAL、BLL 和 Shell。其中,Shell 在此为 Web API。同时,每一层还会有对应的 Model。另外,为了方便网络访问方便,还有一层额外的 HTTP SDK 层。
- DAL 为数据访问层,用于连接上层业务和底层数据库,该层默认已由框架内部完成,因此除非有特别需求需要覆盖,否则可以不用处理。
- BLL 为业务逻辑层,通过对底层数据访问层和其它辅助支持的封装,包含完整的业务逻辑。
- Web API 为通过 HTTP 服务的方式暴露的接口层,其应以进行网络传输数据转化和其它的网络服务扩展为主,而不具备业务处理能力,因这部分转交至业务逻辑层处理。
- HTTP SDK 为对 HTTP 请求进行简易封装的客户端接口访问层。
即 Entity,通过直接或间接继承 BaseResourceEntity 来实现。其为 DAL、BLL、Web API 的统一共用 Model,如果在客户端中应用于 UWP 或 WPF 则还为具备双向绑定能力的 View Model。该类的实现,需要注意一下事项。
- 在类名之上标记
[Table]特性,以指明数据库中的表名。 - 在属性名之上标记
[Column]特性,以指明该属性对应数据库表中的列明。如果该属性不用于映射数据库表中的列,则需标记[NotMapped]特性。 - 在属性名之上标记
[JsonPropertyName]特性,以指明该属性在经 Web API 时,序列化和反序列化所对应 JSON 的属性名。如果该属性无需与 JSON 对应属性匹配,则需标记[JsonIgnore]特性。 - 属性的 get 和 set 实现需分别通过
GetCurrentProperty<T>和SetCurrentProperty方法完成,以确保该属性具备双向绑定的能力,除非该属性用于转换其它属性或者是非重要属性。
通过继承 OnPremisesResourceEntityProvider 类可实现指定 Entity 的访问能力。该基类已预置了最基础的访问能力,可以进行重写和扩展。需要留意的是,构造函数需要至少保留和基类构造函数一致的传参,除此之外可以有额外的构造函数。该类内置的 CoreResources 提供访问当前账户及对应的权限管理等的能力,可用于业务逻辑层内部实现中的鉴权和其它逻辑处理。
当有多个该 Entity 的 Provider 后,可以通过继承 OnPremisesResourceAccessContext 类的方式来对它们进行聚合。继承后,只需在该类中以属性的方式声明所需聚合的各 Provider,访问器需采用 public 并同时包含 get 和 set,类在初始化时会自动赋值。
需要在 Controllers 中实现 ResourceAccessController 类,并添加 [ApiController] 特性,以及 [Route("api")] 和 [Route("nuscien5")] 特性。
另外,对于 BLL 中实现的 OnPremisesResourceEntityProvider 类,可以通过继承 OnPremisesResourceEntityController 的方式,以期自动完成一些最基础的实现,并继续进行扩展。扩展时,GetProviderAsync 方法(需实现)可获得当前 Provider,随后只需简单调用其内对应方法即可。
实现 HTTP SDK 有助于方便客户端项目能快速使用。通过继承 HttpResourceEntityProvider 即可完成,并通过继承 HttpResourceAccessContext 类来完成聚合,类似于 BLL。
建议将解决方案(此处以 SampleProject 名为例)划分为3个项目:Core,包含 Entity 和 HTTP SDK,可取名为 SampleProject;Bll,包含 BLL,可取名为 SampleProject.Bll;Web,包含 Web API,可取名为 SampleProject.Web。如果服务器端项目不打算复用,则可以将 BLL 亦放置于 Web 项目中。
在本示例代码中,为了简洁方便,将 Entity、HTTP SDK 和 BLL 均并入 Bll 项目,包含 Customers 和 Goods 共2个简单示例;而 Web API 仍保留至 Web 项目中;另外,Sql 为必要的数据库准备 TSQL 代码目录。
以 Web 项目中的 CustomerController 为例。其继承了 BaseResourceEntityController<CustomerEntityProvider, CustomerEntity> 类,泛型里的第一个类需要是第二个 Entity 类的 Provider。继承后即意味着这个 Web API Controller 已内建包含根据 ID 获取指定 CutomerEntity、根据 Name 搜索 CustomerEntity 列表、保存指定 CustomerEntity 的基础能力,而这些能力则实际来自于 Bll 项目中的 CustomerEntityProvider,因此继承时需要实现 GetProviderAsync() 方法,但实现的方式则千篇一律都如示例那样,创建一个聚合的 ResourceAccessContext 实现的实例然后从中获得即可,可参考 Web 项目中的 ControllerHelper 中对应的实现。如果希望增加其它接口,那么对此 Controller 添加方法后,在其内先调用 await GetProviderAsync() 即可获得对应的 Entity Provider,随后即可调用调用方法,入参可从 Request 中获得,并最终把结果返回。
而 CustomerEntityProvider 继承自 OnPremisesResourceEntityProvider<CustomerEntity> 类,已包含上述的基础增删改查能力。对于搜寻功能,此类需要重载实现 MapQuery(QueryPredication<CustomerEntity>) 方法,其用于扩展搜索时的字段比较能力。除此之外,还可以重载 SaveAsync 方法以加入权限控制,通过调用 CoreResources 属性即可访问账户相关能力;你还可以增加一些其它方法,通过调用 Set.Where(ele => ...) 方法来获取结果,或者调用 base.SaveAsync 方法来保存。