在ASP.NET Core中使用Apworks快速开发数据服务

不少关注我博客的朋友都知道我在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。这些内容我也会争取抽空跟大家做介绍。

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

原文地址:http://www.cnblogs.com/daxnet/p/6661369.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/326170.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2015蓝桥杯省赛---java---A---1(熊怪吃核桃)

题目描述 代码实现 package TEST; class Main{public static void main(String[] args) {int n1543;int sum0;while (n!1){if(n%20){n/2;}else {sum;n--;}}System.out.println(sum1);} }答案 5

多功能语音播放器上线啦~

应广大学生反映&#xff0c;学程序不会读单词&#xff0c;留言问我能不能做个语音播放器&#xff0c;就是能输入英文能读出来的那种&#xff01;&#xff01;为了帮助公众号里面仅有的几百粉丝&#xff0c;我就顺手写一个吧&#xff0c;万一还能增加点粉丝呢&#xff1f;于是经…

Redis进阶之主从复制

转载自 Redis进阶之主从复制 一、主从复制概述 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Redis服务器。前者称为主节点(master)&#xff0c;后者称为从节点(slave)&#xff1b;数据的复制是单向的&#xff0c;只能由主节点到从节点。 默认…

html图片通过照片查看器打开图片,在Windows7中打开照片,提示“Windows 照片查看器无法显示此图片,因为计算机上...

在Windows7中打开照片&#xff0c;提示“Windows 照片查看器无法显示此图片&#xff0c;因为计算机上的可用内存可能不足。请关闭一些目前没有使用的程序或者释放部分硬盘空间(如果硬盘几乎已满)&#xff0c;然后重试。” 如下图所示&#xff1a;处理过程&#xff1a;1、查看计…

2015蓝桥杯省赛---java---A---3(九数分三组)

题目描述 代码实现 package TEST;class Main{public static void main(String[] args) {for (int i 100; i < 335; i) {if(check(i)){System.out.println(i);}}}public static boolean check(int n){String an""n*2n*3;if(a.contains("1")&&a…

EntityFramework Core不得不注意的性能优化意外收获,你会用错?

前言 这两天在着实研究EF Core项目当中对于一些查询也没实际去检测&#xff0c;于是想着利用放假时间去实际测试下&#xff0c;结果本文就出来了&#xff0c;too young,too simple&#xff0c;后续博主会从底层翻译表达式树弄起&#xff0c;来从源头了解EF Core&#xff0c;通…

微服务为什么离不开spring cloud?

转载自 微服务为什么离不开spring cloud? 现如今微服务架构十分流行&#xff0c;而采用微服务构建系统也会带来更清晰的业务划分和可扩展性。同时&#xff0c;支持微服务的技术栈也是多种多样的&#xff0c;本系列文章主要介绍这些技术中的翘楚——Spring Cloud。这是序篇&a…

html画等边三角形,前台面试:使用CSS画一个等边三角形

CSS是前台面试必考的内容&#xff0c;有时候会面试官会出题让你画少量基本图形。由于画图的过程中可以考察很多的CSS知识点。今天我们就和大家详情一个比较难得等边三角形。思路是利使用三个div的边框来拼成一个三角形&#xff0c;只要要调整好左右两个div边框的旋转角度&#…

2017蓝桥杯省赛---java---A---1(迷宫)

题目描述 X星球的一处迷宫游乐场建在某个小山坡上。 它是由10x10相互连通的小房间组成的。房间的地板上写着一个很大的字母。 我们假设玩家是面朝上坡的方向站立&#xff0c;则&#xff1a; L表示走到左边的房间&#xff0c; R表示走到右边的房间&#xff0c; U表示走到上坡方…

[认证授权] 2.OAuth2授权(续) amp;amp; JSON Web Token

0. RFC6749还有哪些可以完善的&#xff1f; 0.1. 撤销Token 在上篇[认证授权] 1.OAuth2授权 中介绍到了OAuth2可以帮我们解决第三方Client访问受保护资源的问题&#xff0c;但是只提供了如何获得access_token&#xff0c;并未说明怎么来撤销一个access_token。关于这部分OAut…

Nginx动静分离实现负载均衡

转载自 Nginx动静分离实现负载均衡 前期准备 使用Debian环境。安装Nginx(默认安装)&#xff0c;一个web项目&#xff0c;安装tomcat(默认安装)等。 Nginx.conf配置 1 # 定义Nginx运行的用户 和 用户组 如果对应服务器暴露在外面的话建议使用权限较小的用户 防止被入侵2 # …

html5动画是什么,10个HTML5动画 让你忘掉Flash是啥(组图)

你最近可能已经听到了很多关于Flash是面临垂死挣扎的技术以及它将如何很快被HTML5的取代。就个人而言&#xff0c;我认为HTML5会慢慢取代一些Flash的东西&#xff0c;但Flash会永远有它的一席之地&#xff0c;特别是开发复杂的游戏和丰富的互联网应用。如果你还没有看到HTML5动…

2016蓝桥杯省赛---java---A---6(寒假作业)

题目描述 现在小学的数学题目也不是那么好玩的。 看看这个寒假作业&#xff1a;□ □ □ □ - □ □ □ □ □ □ □ □(如果显示不出来&#xff0c;可以参见【图1.jpg】)每个方块代表1~13中的某一个数字&#xff0c;但不能重复。 比如&#xff1a; 6 7 13 9 - 8 1 …

微服务网关Ocelot

微服务网关是微服务架构中的核心组件,它是客户端请求的门户,它是调用具体服务端的桥梁.下面我们将使用开源项目Ocelot&#xff08;https://github.com/geffzhang/Ocelot&#xff09;搭建一款轻量级服务网关,不过在此之前我们将对微服务网关做个详细介绍,以便大家更加清晰的了解…

分表分库时机选择及策略

转载自 分表分库时机选择及策略 一. 分表 应用场景&#xff1a; 对于大型的互联网应用来说&#xff0c;数据库单表的记录行数可能达到千万级甚至是亿级&#xff0c;并且数据库面临着极高的并发访问。采用Master-Slave复制模式的MySQL架构&#xff0c;只能够对数据库的读进…

2015蓝桥杯省赛---java---A---2(星系炸弹)

题目描述 思路分析 方案一 方案二 package TEST;import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date;class Main{public static void main(String[] args) {SimpleDateFormat dateFormat new SimpleDateFormat("yyyy-MM-dd");…

NuGet社区使用体验调查

Nuget 是我们使用.NET Core的一项基础设施&#xff0c;针对国内访问NuGet服务器速度不稳定的问题我们希望通过收集一些来自用户的反馈来改善社区使用NuGet的体验。恳请您花2-3分钟时间完成以下的问题&#xff0c;我们会非常重视您的反馈。当我们收集完成所有的问卷&#xff0c;…

在护卫神上部署javaWeb项目,已经测试通过

以前一直在护卫神上部署PHP项目&#xff0c;今天忽然来了需求是部署javaWeb项目&#xff0c;刚开始一脸蒙蔽&#xff0c;后来发现也不是很难。那么接下来我们看看怎么在护卫神上部署java项目&#xff1a; 第一步&#xff1a;打开护卫神&#xff0c;在护卫神中添加一个网站&…

为什么选择微服务架构?如何取舍?

转载自 为什么选择微服务架构&#xff1f;如何取舍&#xff1f; 微服务是什么 微服务是一种架构风格&#xff0c;一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署&#xff0c;各个微服务之间是松耦合的。每个微服务仅关注于完成…

三星系统和鸿蒙系统,又一设备直升鸿蒙系统,现有操作系统被抛弃,和三星的想法一样!...

又一设备直升鸿蒙系统&#xff0c;现有操作系统被抛弃&#xff0c;和三星的想法一样&#xff01;前段时间华为正式发布了鸿蒙系统&#xff0c;这个系统可以说是期待已久了&#xff0c;在华为处于禁令时期时&#xff0c;鸿蒙被认为是替代安卓的操作系统。在鸿蒙发布后&#xff0…