NET Core2.0 实现Slickflow.NET开源工作流引擎

来源:slickflowteam

cnblogs.com/slickflow/p/8250317.html

前言

.NET Core 是.NET Framework的新一代版本,是微软开发的第一个跨平台 (Windows、Mac OSX、Linux) 的应用程序开发框架(Application Framework),未来也将会支持 FreeBSD 与 Alpine 平台。

.NET Core也是微软在一开始发展时就开源的软件平台,其开发目标是跨平台的 .NET 平台。

.NET Core 平台的开发优势 :

支持或可以移转 (port) 到更多的操作系统平台与芯片架构 (也就是未来项目会跨出 x86 平台)。

具有引人注目的性能与高可靠度。

开发人员能快速与直觉的获取 .NET Core 开发环境。

在直觉与具生产力的情况下建造应用程序,使用文件,示例与 NuGet 组件。

以上文字引用来源:https://zh.wikipedia.org/wiki/.NET_Core

一、.NET Core 2.0 迁移指南

由于.NET Core跨平台开发和性能方面的优势,再加上.NET Core2.0版本的推出,越来越多的客户逐渐迁移到.NET Core框架进行软件系统的开发。Slickflow引擎组件的.NET Core版本的推出,也是为了解决跨平台引擎产品的实现。

本文大致描述了创建.NET Core2.0 为目标版本类库,数据访问项目和Asp.NET Mvc Core等类型项目的搭建过程,方便用户快速上手。

1.1、数据访问项目

1) IRepository模式实现

Repository模式实现通用数据访问接口,其好处是首先定义出标准的增删改查接口,其次可以满足对接后端不同的数据处理框架,如Dapper,EF和NHibernate等框架。

///

/// 数据操作类接口

///

/// 数据实体类型

public interface IRepository where T : class

{

DbSet GetDbSet();

T GetByID(dynamic id);

T Get(Expression> predicate);

IQueryable GetAll();

IQueryable Query(string sql, params object[] parameters);

IEnumerable Query(Expression> predicate);

int Count(Expression> predicate = null);

//insert, update, delete

T Insert(T entity);

void Insert(params T[] entities);

void Insert(IEnumerable entities);

void Update(T entity);

void Update(params T[] entities);

void Update(IEnumerable entities);

void Delete(dynamic id);

void Delete(params T[] entities);

void Delete(IEnumerable entities);

}

2) UnitOfWork 解决事务

引擎内部逻辑处理通常是多表的插入编辑操作,为保持数据事务完整性,需要实现会话事务的参数传递,提供提交和回滚的处理方式。Slickflow.Data.IDbSession用来实现UnitOfWork模式。

///

/// 数据会话接口

///

public interface IDbSession : IDisposable

{

DbContext DbContext { get; }

IRepository GetRepository() where T : class;

int SaveChanges();

int ExecuteSqlCommand(string sql, params object[] paramters);

}

代码示例:Session作为参数,传入具体接口方法,最终实现事务的一致提交或回滚。

///

/// 运行流程测试

///

///

运行者

/// 执行结果

[HttpPost]

public ResponseResult RunProcessApp([FromBody] WfAppRunner runner)

{

using (var session = DbFactory.CreateSession())

{

var transaction = session.DbContext.Database.BeginTransaction();

var wfService = new WorkflowService();

var result = wfService.RunProcessApp(runner, session);

if (result.Status == WfExecutedStatus.Success)

{

transaction.Commit();

return ResponseResult.Success();

}

else

{

transaction.Rollback();

return ResponseResult.Error(result.Message);

}

}

}

1.2、ASP.NET MVC Core项目

1) Mvc和WebAPI路由统一配置

通常在.NET项目开发中,Mvc项目用于前端页面展现,WebAPI用于后端接口实现。在项目实践过程中,可以将两个项目整合为一,便于环境配置。

app.UseMvc(route => {

route.MapRoute(

name: "default",

template: "//");

route.MapRoute(

name:"defaultApi",

template: "api///");

});

2) 数据库连接串配置

数据库链接串在appsettings.json文件中进行定义,读取方法如下:

var dbType = ConfigurationExtensions.GetConnectionString(Configuration, "WfDBConnectionType");

var sqlConnectionString = ConfigurationExtensions.GetConnectionString(Configuration, "WfDBConnectionString");

Slickflow.Data.ConnectionString.DbType = dbType;

Slickflow.Data.ConnectionString.Value = sqlConnectionString;

3) DbContext 数据库类型匹配

由于不同类型数据库的数据访问组件不同,所以特意做了接口对应匹配,传入数据库连接串值。

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)

{

if (ConnectionString.DbType == DatabaseTypeEnum.SQLSERVER.ToString())

optionsBuilder.UseSqlServer(ConnectionString.Value);

else if (ConnectionString.DbType == DatabaseTypeEnum.MYSQL.ToString())

optionsBuilder.UseMySql(ConnectionString.Value);

else if (ConnectionString.DbType == DatabaseTypeEnum.ORACLE.ToString())

optionsBuilder.UseOracle(ConnectionString.Value);

}

二、EF Core对多数据库生成的支持

EF Code First是由实体来生成数据库模型,简要过程描述为:首先定义好实体对象,对应数据库字段类型,然后执行EF Migrations的操作命令来生成数据库对象。其中经常用到的命令有:

1) dotnet ef migrations add MyFirstMigraton

2) dotnet ef migrations update database

下面就以WfProcess表的创建来说明大致的创建过程。

2.1 MS SQLSERVER数据库

采用的数据访问组件默认为:Microsoft.EntityFrameworkCore。

1) 实体属性标识

///

/// 流程实体类

///

[Table("WfProcess")]

public class ProcessEntity

{

[Key]

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

[Column(Order = 0)]

public int ID { get; set; }

[Required]

[Column(TypeName = "varchar(100)", Order = 1)]

[MaxLength(100)]

public string ProcessGUID { get; set; }

[Required]

[Column(TypeName = "nvarchar(50)", Order = 2)]

[MaxLength(50)]

public string ProcessName { get; set; }

[Required]

[Column(TypeName ="nvarchar(20)", Order = 3)]

[MaxLength(20)]

public string Version { get; set; }

}

2) 默认值赋值

//流程创建

modelBuilder.Entity

(entity =>

{

entity.Property(e => e.Version).HasDefaultValue("1");

entity.Property(e => e.IsUsing).HasDefaultValue(0);

entity.Property(e => e.StartType).HasDefaultValue(0);

entity.Property(e => e.EndType).HasDefaultValue(0);

entity.Property(e => e.CreatedDateTime).HasDefaultValueSql("getdate()");

});

3) 生成命令执行

dotnet ef migrations add MyFirstMigration

2.2、MySQL数据库

采用的数据访问组件默认为:Polemo.EntityFrameworkCore.MySQL。

1) 实体属性标识

///

/// 流程实体类

///

[Table("WfProcess")]

public class ProcessEntity

{

[Key]

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

[Column(Order = 0)]

public int ID { get; set; }

[Required]

[Column(TypeName = "varchar(100)", Order = 1)]

[MaxLength(100)]

public string ProcessGUID { get; set; }

[Required]

[Column(TypeName = "varchar(50)", Order = 2)]

[MaxLength(50)]

public string ProcessName { get; set; }

[Required]

[Column(TypeName ="varchar(20)", Order = 3)]

[MaxLength(20)]

public string Version { get; set; }

}

2) 默认值赋值

//流程创建

modelBuilder.Entity

(entity =>

{

entity.Property(e => e.Version).HasDefaultValue("1");

entity.Property(e => e.IsUsing).HasDefaultValue(0);

entity.Property(e => e.StartType).HasDefaultValue(0);

entity.Property(e => e.EndType).HasDefaultValue(0);

});

3) 生成命令执行

dotnet ef migrations add MyFirstMigration

三、Slickflow.WebAPI 快速测试

3.1、路由模式选定:

仍然选定传统路由模式,便于接口快速识别和匹配。

app.UseMvc(route => {

route.MapRoute(

name: "defaultApi",

template: "api///");

});

3.2 、数据库链接串读取:

var dbType = ConfigurationExtensions.GetConnectionString(Configuration, "WfDBConnectionType");

var sqlConnectionString = ConfigurationExtensions.GetConnectionString(Configuration, "WfDBConnectionString");

Slickflow.Data.ConnectionString.DbType = dbType;

Slickflow.Data.ConnectionString.Value = sqlConnectionString;

3.3、测试接口方法

///

/// 启动流程测试

///

///

运行者

/// 执行结果

[HttpPost]

public ResponseResult StartProcess([FromBody] WfAppRunner runner)

{

using (var session = DbFactory.CreateSession())

{

var transaction = session.DbContext.Database.BeginTransaction();

var wfService = new WorkflowService();

var result = wfService.StartProcess(runner, session);

if (result.Status == WfExecutedStatus.Success)

{

transaction.Commit();

return ResponseResult.Success();

}

else

{

transaction.Rollback();

return ResponseResult.Error(result.Message);

}

}

}

3.4、RestClient 测试工具

引擎接口测试采用RestClient工具,比较方便快捷。通常采用统一的接口方法,将不同类型的流程JSON数据格式作为测试用例来提交测试。

四、总结

Slickflow 引擎产品的.NET Core版本实现,用于跨平台应用的项目开发和业务集成。而且在数据库的支持上,采用EF Core的Code First数据库迁移创建,方便用户开发环境的快速搭建和配置。

看完本文有收获?请转发分享给更多人

关注「DotNet」,提升.Net技能

淘口令:复制以下红色内容,再打开手淘即可购买

范品社,使用¥极客T恤¥抢先预览(长按复制整段文案,打开手机淘宝即可进入活动内容)

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180404B0M2GX00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券