不少关注我博客的朋友都知道我在2009年左右开发过一个名为Apworks的企业级应用程序开发框架,旨在为分布式企业系统软件开发提供面向领域驱动(DDD)的框架级别的解决方案,并对多种系统架构风格提供支持。这个框架的开发和维护我坚持了很久,一直到2015年,我都一直在不停地重构这个项目。目前这个项目在Github上也得到了将近260的推荐数,很多对技术感兴趣的朋友也一直与我保持着联系和交流,甚至还有爱好者自发组成了技术讨论群,专门讨论分享Apworks框架。

然而,随着软件开发技术和.NET的发展,这个框架的设计和研发技术都逐渐过时,重构难度逐渐加大,很多由其本身支持的技术,比如MSMQ、NHibernate也都逐渐淡出人们的视线,相比之下,云计算、微服务、大数据、跨平台等相关技术越来越多地引起了业界的关注,成功的案例也越来越多。如何基于云平台(PaaS + IaaS)快速搭建高效、经济、稳定、安全的软件系统架构,成为了最近两年的热门话题。微软也顺应这样的潮流,做出了很多的改变,就在短短的一到两年时间,引领了.NET的跨平台,开源了诸多著名的项目,比如.NET、Core CLR、Roslyn、ASP.NET、Entity Framework、Powershell等等,并且开始接受并拥抱非Windows的操作系统,比如Visual Studio跨平台、Powershell跨平台、SQL Server跨平台、Visual C++支持多种编译器等等。很明显,原有的Apworks已经不再具备跨平台、云友好、开发迅速的特质,为此,我下定决心重写了Apworks。

全新的Apworks Core应用程序开发框架

新的Apworks Core也是开源项目,该项目依旧基于Apache 2.0许可协议,项目地址是:https://github.com/daxnet/apworks-core。目前仍然还在继续开发阶段,仅实现了原有DDD中的基本概念(实体、聚合、实体键、仓储等),并针对内存并发字典(Concurrent Dictionary)、MongoDB以及Entity Framework Core完成了三种不同的仓储实现,整个框架完全由.NET Core实现(目前提供net461和Net Standard 1.6两种编译),因此,可以使用在Windows的经典.NET Framework下,也可以使用在Linux的.NET Core中。不仅如此,针对ASP.NET Core Web API,Apworks提供了相应的整合与扩展,使得数据服务的开发变得非常简单方便,这也是本文准备介绍的内容,相信在阅读本文之后,你将更多地了解到Apworks Core的开放性和扩展性,并能体会到在.NET应用程序的开发生态圈中,Apworks Core将会给你带来更多的帮助。

演练:使用Apworks Core快速开发数据服务

在开始我们的Apworks Core开发演练之前,请先完成以下准备工作:

  1. 安装Visual Studio 2017,确保.NET Core和ASP.NET Core的开发功能已经正确安装
  2. https://www.myget.org/F/daxnet-apworks-pre/api/v3/index.json以及https://www.myget.org/F/daxnet-utils/api/v3/index.json两个package source添加到NuGet的package source中:

  3. 准备一个MongoDB的数据库服务器,建议直接下载Windows版本的搭建在本地机器,也可以在Linux下直接运行mongo的Docker容器,省去了安装MongoDB的步骤
  4. 如果希望能一起尝试Visual Studio 2017的Docker功能,还需要确保安装最新版本的Windows以及Docker for Windows。当然,完成本文的演练并不需要Docker

开发步骤

  1. 首先,新建一个ASP.NET Core的应用程序,名为CustomerService,通过Manage NuGet Packages添加对Apworks.Repositories.MongoDB以及Apworks.Integration.AspNetCore的引用。添加引用的时候注意选择https://www.myget.org/F/daxnet-apworks-pre/api/v3/index.json这个package source:

  2. 在CustomerService下新建一个Models目录,添加两个类,名称分别为Address和Customer,代码如下:
    public class Address
    {
    public string Country { get; set; }
    public string State { get; set; }
    public string City { get; set; }
    public string Street { get; set; }
    public string ZipCode { get; set; }
    } public class Customer : IAggregateRoot<Guid>
    {
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public Address ContactAddress { get; set; }
    }
  3. 在Controllers子目录下,新建一个Controller,取名为CustomersController,代码如下:
    public class CustomersController : DataServiceController<Guid, Customer>
    {
    public CustomersController(IRepositoryContext repositoryContext) : base(repositoryContext)
    {
    }
    }
  4. 打开Startup.cs文件,在ConfigureServices方法中,加入以下代码:
    public void ConfigureServices(IServiceCollection services)
    {
    // Add framework services.
    services.AddMvc(); services.AddApworks()
    .WithDataServiceSupport(new DataServiceConfigurationOptions
    (new MongoRepositoryContext
    (new MongoRepositorySettings("localhost", "customer-service"))))
    .Configure();
    }
  5. 同样在Startup.cs文件中,在Configure方法中,加入以下代码:
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug(); app.EnrichDataServiceExceptionResponse(); app.UseMvc();
    }
  6. OK, you’re all set! 完成之后,解决方案资源管理器中的项目结构如下,增加了一个Models目录,以及一个CustomersController:

编译运行

直接按下Ctrl + F5运行站点,站点起来后,你会发现浏览器打开的内容跟标准的新建的ASP.NET Core Web API项目无异,显示的是由ValuesController的GET方法返回的两个字符串。不用着急,打开Fiddler,我们简单测试一下刚刚新建的Customer数据服务(注意替换一下URL,我本地服务运行在2238端口上):

  1. POST http://localhost:2238/api/customers

    POST操作成功返回HTTP 201,同时在Response Body中返回了新建的对象Id。

  2. GET http://localhost:2238/api/customers

限于篇幅,此处就不针对所有基本的HTTP操作一一进行测试了。Apworks Data Service默认支持以下HTTP方法,当然,你可以随意扩展:

  1. GET:获取所有的对象,默认支持服务端分页,每页15条记录,可以通过http://localhost:2238/api/customers?page=aaa&size=bbb这样的格式来指定每页大小以及需要获取的页码
  2. GET {id}:http://localhost:2238/api/customers/{id}:获取Id值为{id}的对象
  3. POST {id}:替换Id值为{id}的对象,替换成功则返回HTTP 204(No Content)
  4. PATCH {id}:更新id值为{id}的对象,Request Body需要符合Microsoft ASP.NET Json Patch的规范。更新成功返回HTTP 204(No Content)
  5. DELETE {id}:删除id值为{id}的对象。删除成功返回HTTP 204(No Content)

几个亮点

  1. 开发和配置过程及其简单,如上所述,五个步骤完成一个数据对象的数据服务开发。流畅接口(Fluent API)配置方式,使得数据服务的开发过程与已有ASP.NET Core Web API的开发过程具有相同的开发者体验
  2. HTTP GET调用默认支持服务端分页,分页链接会通过HAL标记体现在返回结果中
  3. HTTP GET返回直接支持Hypertext Application Language(HAL,官方网站:http://stateless.co/hal_specification.html),返回Content-Type为application/hal+json。它是通过我的另一个开源项目https://github.com/daxnet/hal 实现的,HAL项目在.NET Core下完整、全面地实现了HAL规范,并且通过流畅接口(Fluent API)的方式,提供了较好的开发者体验。通过Apworks Core开发数据服务时,开发者可以通过设定DataServiceConfigurationOptions参数,选择是否需要HAL支持,还可以扩展HalBuildConfiguration类型,以实现HAL返回结果的自定义
  4. 仓储实现可以选择使用In-Memory Concurrent Dictionary、MongoDB以及Entity Framework Core,整个技术栈完全跨平台。如果使用Entity Framework Core,目前EF Core对SQL Server、PostgreSQL以及SQLite的支持都不错,对于Oracle等也有相应的Provider支持,因此,可以选择各种不同的关系型数据库来基于Apworks Core快速实现数据服务
  5. 加入EnrichDataServiceExceptionResponse方法可以使得当错误发生时,数据服务的返回结果将包含更为准确的错误代码和错误信息

对于三种目前支持的仓储的使用方式、HAL返回结果自定义,以及数据服务的扩展这些内容,我今后再慢慢介绍吧,这里就不多说了。

总结

现在,Apworks Core仅仅是刚刚开始,接下来还有很长的路要走,单从数据服务和ASP.NET Core的整合这部分,还需要更加丰富的功能,比如API的帮助页面、查询条件和排序条件的指定等等。查询条件的支持我打算使用我迁移的一个开源的.NET语法分析框架:Irony项目来完成。之后,我还是会像往常一样,基于Apworks Core实现一个完整的应用案例,来演示Apworks Core各方面的功能。

另一方面,Apworks Core的项目分支策略和持续集成也是可以拿来分享的。我没有开放Apworks Core持续集成系统,但任何人都可以通过项目的Github主页了解到最新构建的状态,也可以看到最新preview和release版本的package source。Apworks Core同时在Windows Server和Ubuntu Linux下完成编译,编译完全采用Powershell脚本完成,因此,对于Linux系统,需要首先安装Powershell。这些内容我也会争取抽空跟大家做介绍。

最后,还是那句话,大家多多交流,多提宝贵意见吧。我争取做得更好。

在ASP.NET Core中使用Apworks快速开发数据服务的更多相关文章

  1. 在ASP.NET Core中使用Apworks开发数据服务:对HAL的支持

    HAL,全称为Hypertext Application Language,它是一种简单的数据格式,它能以一种简单.统一的形式,在API中引入超链接特性,使得API的可发现性(discoverable ...

  2. 在ASP.NET Core中如何支持每个租户数据存储策略的数据库

    在ASP.NET Core中如何支持每个租户数据存储策略的数据库 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: ht ...

  3. 汇总:ASP.NET Core中HttpContext获取传参数据,有哪些方式

    一.原生方式: 1.POST(以ajax请求为案例,教大家用法) $.ajax({ type: "post", dataType: "json", cache: ...

  4. NET Core中使用Apworks

    NET Core中使用Apworks HAL,全称为Hypertext Application Language,它是一种简单的数据格式,它能以一种简单.统一的形式,在API中引入超链接特性,使得AP ...

  5. ASP.NET Core中返回 json 数据首字母大小写问题

    ASP.NET Core中返回 json 数据首字母大小写问题 在asp.net core中使用ajax请求动态绑定数据时遇到该问题 后台返回数据字段首字母为定义的大写,返回的数据没有问题 但是在前台 ...

  6. 浅谈ASP.NET Core中的DI

    DI的一些事 传送门马丁大叔的文章 什么是依赖注入(DI: Dependency Injection)?     依赖注入(DI)是一种面向对象的软件设计模式,主要是帮助开发人员开发出松耦合的应用程序 ...

  7. 从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用ApplicationPart动态加载控制器和视图

    标题:从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用Application Part动态加载控制器和视图 作者:Lamond Lu 地址:http://www.cnblogs ...

  8. C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持 基于EF Core的Code First模式的DotNetCore快速开发框架 【懒人有道】在asp.net core中实现程序集注入

    C# 嵌入dll   在很多时候我们在生成C#exe文件时,如果在工程里调用了dll文件时,那么如果不加以处理的话在生成的exe文件运行时需要连同这个dll一起转移,相比于一个单独干净的exe,这种形 ...

  9. 如何在ASP.NET Core 中快速构建PDF文档

    比如我们需要ASP.NET Core 中需要通过PDF来进行某些简单的报表开发,随着这并不难,但还是会手忙脚乱的去搜索一些资料,那么恭喜您,这篇帖子会帮助到您,我们就不会再去浪费一些宝贵的时间. 在本 ...

随机推荐

  1. php连接 mysql 数据库

    php 连接数据库 一般是用面向对象的方法,需要先创建一个对象,即造一个连接对象,然后再写sql语句,(增改查删),最后执行sql语句 其中在创建连接对象时 我们用到的是MySQLI  是不区分大小写 ...

  2. JUnit与JMock学习

    JUnit与JMock学习 测试驱动编程和持续集成部署应该说是现在软件开发者的必备武器,不过跟其他很多好东西一样,在我们公司的推广总要慢上一拍,毕竟老板看的是你能够把功能实现好让客户满意,所以能不折腾 ...

  3. JUC学习笔记--从阿里Java开发手册学习线程池的正确创建方法

    前言 最近看阿里的 Java开发手册,上面有线程池的一个建议: [强制]线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式, 这样的处理方式让写的同学 ...

  4. 【原创】python中文编码问题深入分析(二):print打印中文异常及显示乱码问题分析与解决

    在学习python以及在使用python进行项目开发的过程中,经常会使用print语句打印一些调试信息,这些调试信息中往往会包含中文,如果你使用python版本是python2.7,或许你也会遇到和我 ...

  5. 05String字符串课后作业

    1.请运行以下示例代码StringPool.java,查看其输出结果.如何解释这样的输出结果?从中你能总结出什么? 由此可得出,用加号连接的字符串和一整个字符串相同代码判断是true,而新开辟空间的不 ...

  6. 关于Xmanager使用问题的总结

    做大数据的人对Xmanager这类远程连接工具应该都不陌生,我在使用Xmanager时遇到了一些问题并经过google和亲测解决,写在这里与大家分享. 1. [问题描述] 在windows上使用Xma ...

  7. Java并发之任务的描述和执行

    简单概念 <Java编程思想>对并发概念的重要性阐述: Java是一种多线程语言,并且提出了并发问题,不管你是否意识到了.因此,有很多使用中的Java程序,要么只是偶尔工作,要么是在大多数 ...

  8. 通过udev创建ASM共享磁盘(RAC)

    OS:RedHat EL6.0 Oracle:   Oracle 11gR2 在Oracle 11gR2,构建RAC时可以通过ASM创建asm disk,但是需要安装asmlib相关软件:对于RedH ...

  9. TextView加边框,自定义,上下左右四条线 颜色,想用哪个用哪个

    1.这是一个自定义的TextView ,看吧,底下就是代码,应该都可以看懂,这里就不多说了 package com.example.admin.myutilsborder;import android ...

  10. ehcache memcache redis 区别

    之前用过redis 和 memcache ,没有ehcache 的开发经验,最近也查阅不少文档和博客,写一些总结,也有不少内容总结与诸多博客中的博主总结:  Ehcache EhCache 是一个纯J ...