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