前言:.NET Core 是.NET Framework的新一代版本,是微软开发的第一个跨平台 (Windows、Mac OSX、Linux) 的应用程序开发框架(Application Framework),未来也将会支持 FreeBSD 与 Alpine 平台。.Net Core也是微软在一开始发展时就开源的软件平台,其开发目标是跨平台的 .NET 平台。

.NET Core 平台的开发优势 :

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

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

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

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

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

1. .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等框架。

/// <summary>
    /// 数据操作类接口
    /// </summary>
    /// <typeparam name="T">数据实体类型</typeparam>
    public interface IRepository<T> where T : class
    {
        DbSet<T> GetDbSet();
 
        T GetByID(dynamic id);
        T Get(Expression<Func<T, bool>> predicate);
        IQueryable<T> GetAll();
 
        IQueryable<T> Query(string sql, params object[] parameters);
        IEnumerable<T> Query(Expression<Func<T, bool>> predicate);
        int Count(Expression<Func<T, bool>> predicate = null);
 
 
        //insert, update, delete
        T Insert(T entity);
        void Insert(params T[] entities);
        void Insert(IEnumerable<T> entities);
        void Update(T entity);
        void Update(params T[] entities);
        void Update(IEnumerable<T> entities);
        void Delete(dynamic id);
        void Delete(params T[] entities);
        void Delete(IEnumerable<T> entities);
    }

2) UnitOfWork 解决事务

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

/// <summary>
/// 数据会话接口
/// </summary>
public interface IDbSession : IDisposable
{
    DbContext DbContext { get; }
    IRepository<T> GetRepository<T>() where T : class;
    int SaveChanges();
    int ExecuteSqlCommand(string sql, params object[] paramters);
}

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

/// <summary>
        ///  运行流程测试
        /// </summary>
        /// <param name="runner">运行者</param>
        /// <returns>执行结果</returns>
        [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: "{controller=Home}/{action=Index}/{id?}");
 
                route.MapRoute(
                    name:"defaultApi",
                    template: "api/{controller}/{action}/{id?}");
            });

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);
}

2. 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) 实体属性标识

/// <summary>
   /// 流程实体类
   /// </summary>
   [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<ProcessEntity>(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) 实体属性标识

/// <summary>
/// 流程实体类
/// </summary>
[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<ProcessEntity>(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

3. Slickflow.WebAPI 快速测试

3.1 路由模式选定:

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

app.UseMvc(route => {
    route.MapRoute(
        name: "defaultApi",
        template: "api/{controller}/{action}/{id?}");
});

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 测试接口方法

/// <summary>
///  启动流程测试
/// </summary>
/// <param name="runner">运行者</param>
/// <returns>执行结果</returns>
[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数据格式作为测试用例来提交测试。

4. 总结

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

原文地址:http://www.cnblogs.com/slickflow/p/8250317.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

Slickflow.NET 开源工作流引擎基础介绍-.NET Core2.0 版本实现介绍 (转)的更多相关文章

  1. Slickflow.NET 开源工作流引擎基础介绍(九) -- .NET Core2.0 版本实现介绍

    前言:.NET Core 是.NET Framework的新一代版本,是微软开发的第一个跨平台 (Windows.Mac OSX.Linux) 的应用程序开发框架(Application Framew ...

  2. Slickflow.NET 开源工作流引擎基础介绍(二) -- 引擎组件和业务模块的交互

    集成流程引擎的必要性 业务过程的变化是在BPM系统中常见的现象,企业管理层需要不断优化组织架构,改造业务流程,不可避免地带来了业务流程的变化,企业信息系统就会随之面临重构的可能性.一种直接的方式是改造 ...

  3. Slickflow.NET 开源工作流引擎基础介绍(二) -- 引擎组件和业务系统的集成

    集成流程引擎的必要性 业务过程的变化是在BPM系统中常见的现象,企业管理层需要不断优化组织架构,改造业务流程,不可避免地带来了业务流程的变化,企业信息系统就会随之面临重构的可能性.一种直接的方式是改造 ...

  4. Slickflow.NET 开源工作流引擎基础介绍(七) -- 并行分支多实例模式实现

    前言:并行审批是比较常见的流程模式,在工作流模式介绍中,通常是多个分支通过网关(Gateway)来控制实现.默认的分支类型是静态定义好的.本文扩展了并行网关的控制方式,实现了动态多实例的并行分支网关, ...

  5. Slickflow.NET 开源工作流引擎基础介绍(六)--模块化架构设计和实践

    前言:在集成Slickflow.NET 引擎组件过程中,引擎组件需要将用户,角色等资源数据读取进来,供引擎内部调用:而企业客户都是有自己的组织架构模型,在引入模块化架构设计后,引擎组件的集成性更加友好 ...

  6. Slickflow.NET 开源工作流引擎基础介绍(一) -- 引擎基本服务接口API介绍

    1. 工作流术语图示                                              图1 流程图形的BPMN图形元素表示 1) 流程模型定义说明流程(Process):是企 ...

  7. Slickflow.NET 开源工作流引擎基础介绍(八) -- 自动化任务调度实现介绍

    前言:审批流程中常见的都是人工类型任务,但是也会有一些自动化的任务需要定时触发.因此,引擎框架中需要解决掉两个问题:选择合适的任务调度框架,集成新的任务调度模块. 1. 任务调度框架选择 Hangfi ...

  8. Slickflow.NET 开源工作流引擎基础介绍(四) -- 多数据库支持实现

    前言:引擎作为中间件集成到用户的项目里面去,针对用户的数据库类型,需要作出SQL部分的分别实现.引擎默认数据库为MS SQLSERVER,同时也支持ORACLE, MYSQL, KINGBASE等不同 ...

  9. Slickflow.NET 开源工作流引擎基础介绍(五) -- 会签加签高级特性介绍

    前言:会签和加签是常见审批流程模式,在引擎中,对这两种流程模式做了分别定义和实现,其中也用到了Workflow Pattern的Multiple Instance(多实例) . 1. 会签和加签的定义 ...

随机推荐

  1. B - Factors of Factorial

    Problem Statement You are given an integer N. Find the number of the positive divisors of N!, modulo ...

  2. Python从小看到大

    最近迷恋上了python,因为一个朋友说python这种脚本语言很厉害,可以做网络攻防的时候用,但是由于自己太笨了,不得不从基础教程学起. 行左右.你可能会问为什么这么少的代码量,这门语言没有火起来, ...

  3. uoj#422. 【集训队作业2018】小Z的礼物(MIn-Max容斥+插头dp)

    题面 传送门 题解 好迷-- 很明显它让我们求的是\(Max(S)\),我们用\(Min-Max\)容斥,因为\(Min(S)\)是很好求的,只要用方案数除以总方案数算出概率,再求出倒数就是期望了 然 ...

  4. P1592 互质

    题意:输入两个正整数n和k,求与n互质的第k个正整数. $n≤10^6,k≤10^8$ 可以枚举出互质的数,居然发现,有循环节.... 比如10 与其互质的1  3  7  9  11  13  17 ...

  5. kindedtor的基本使用

    首先需要进入官网下载kineditor相关文件: 然后写代码: <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  6. linux 底层 基础命令 路径信息

    z基础命令: 打印 :echo "hello world“ 切换目录   cd  / 显示当前路径     pwd 显示 目录下所有文件     ls 显示所有文件包括隐藏文件    ls ...

  7. shell编程上

    1.1  前言 1.1.1  为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应用软件的核心大都涉及Shel ...

  8. about rand and reflect

    select regexp_replace(reflect("java.util.UUID", "randomUUID"), "-", &q ...

  9. OpenCV教程(转自:浅墨_毛星云博客)

    2.图像的载入,显示和输出 一站式完全解析 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/detail ...

  10. Problem07 处理字符串

    题目:输入一行字符,分别统计出其中英文字母.空格.数字和其它字符的个数. 程序分析:利用while 语句,条件为输入的字符不为'\n'. import java.util.*; public clas ...