zoukankan      html  css  js  c++  java
  • Slickflow.NET 开源工作流引擎基础介绍-.NET Core2.0 版本实现介绍 (转)

    前言:.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

  • 相关阅读:
    第23条:通过委托与数据源协议进行对象间通信
    第22条:理解NSCopying协议
    第21条:理解Objective-C错误模型
    第20条:为私有方法名加前缀
    《隐藏键盘》《隐藏PickerView控键》如果是xib中 点击空白处隐藏键盘
    《弹出提示》UIAlertView 弹出提示
    MAC 问题。
    小技巧
    控制器的生命周期
    问题。控制器跳转
  • 原文地址:https://www.cnblogs.com/qiulang/p/8714755.html
Copyright © 2011-2022 走看看