本次將要很你們分享的是一個跨平臺運行的服務插件 - TaskCore.MainForm,此框架是使用.netcore來寫的,如今netcore已經支持不少系統平臺運行了,因此將之前的Task.MainForm改良成跨平臺的服務共你們使用和相互交流;原本這篇應該分享的是nginx+iis+redis+Task.MainForm構建分佈式架構後續文章,但使用.netcore來定義一個服務插件和跨平臺測試通過讓我既興奮又頭痛,不說了下次再分享分佈式後續文章吧;那麼開始今天的分享內容,但願各位多多支持:html
. 框架結構介紹及運行效果圖nginx
. 如何生成nuget包和使用開源框架TaskCore.MainFormgit
. win7和ubuntu16.04運行TaskCore.MainForm的兩種方式和測試截圖(也可認爲.netcore項目在win7和ubuntu系統運行的兩種方式)github
. 框架代碼解讀及感悟redis
下面一步一個腳印的來分享:json
. 框架結構介紹及運行效果圖ubuntu
首先,咋們先來認識下項目源碼的工程目錄結構如圖:windows
結構看上去應該夠清晰了,源碼文件量也不多,不過的確實現了動態加載程序集dll來執行任務,後面會給出相應的執行截圖,咱們再來看下TaskCore.MainForm項目經過vs2015生成以後Bin文件夾中的文件如圖:架構
若是安裝了.netcore sdk的話在windows上您只須要上面截圖的文件就能運行插件了;再來咱們在已經安裝過core sdk的win7系統上執行一下以下命令 dotnet TaskCore.MainForm.dll 就能看到如圖的效果:app
沒錯這就是插件運行起來的效果圖,由於.netcore現目前暫時沒有提供相似於winform那樣的皮膚界面效果,全部只能經過命令行來作跨平臺運行程序
. 如何生成nuget包和使用TaskCore.MainForm
首先,咱們要明確服務是由兩部分構成(TaskCore.MainForm和TaskCore.Plugin);TaskCore.MainForm主要用來運行程序,TaskCore.Plugin用來做爲子任務須要繼承的父類插件;當咱們下載TaskCore.MainForm運行包以後(如圖2結構),咱們還須要作的就是繼承TaskCore.Plugin.dl中的TPlugin這個類,來重寫本身的任務內容,所以咱們新建一個項目取名爲:TaskCore.Test,再來咱們經過vs2015引用功能直接添加TaskCore.MainForm運行包中的TaskCore.Plugin.dl引用,這個時候會提示一個錯誤:
錯誤意思是無法加載netcore版本的dll,所以這種直接在vs項目中引用方式添加dll依賴不行,須要經過nuget來添加依賴包(.netcore對類庫的引用目前只能經過nuget來安裝依賴,這個須要注意),因此我這裏把TaskCore.Plugin項目經過 dotnet pack 命令來生成nuget包,而後以便我TaskCore.Test項目中來使用;
如何生成nuget包(win7系統dotnet命令來生成包的過程和下載):
直接在vs中右鍵您須要打包的類庫項目-》選擇"在資源管理器中打開文件夾"-》這樣就到了您類庫的根目錄,而後退到類庫根目錄的上一級文件夾中-》按住鍵盤」shift"鍵並同時鼠標右鍵要打包類庫的項目文件件(我這裏是TaskCore.Plugin文件夾)-》選擇「在此處打開命令窗體」 這個時候就進入了cmd命令窗體,固然有些朋友直接喜歡直接先cmd再來找對應的磁盤,反正我以爲第一種更快點(不一樣人不一樣選擇吧),下面看下操做截圖:
由上圖能夠看到,經過命令生成了nupkg文件,這文件就是咋們須要在項目中下載安裝的TaskCore.Plugin插件包;接下來咱們來在TaskCore.Test項目中安裝這個插件以下步奏,右鍵TaskCore.Plugin項目中的「引用」-》選擇「管理nuget程序包」-》而後選擇右上角的這個圖標
-》選擇「Nuget包管理器」-》「程序包源」-》
-》而後選擇新建立的包源,下面設置如圖
這裏的「源(S)」指定的本地路徑就是剛纔咱們生成的nupkg文件文件的磁盤(固然我這裏是吧剛纔pack命令生成的文件複製到了MyNugPackage文件夾中方便測試)-》而後點擊」肯定「按鈕-》而後在返回到
選擇咱們的包源MyNugPackage-》再瀏覽這裏就能看到咱們建立的nuget包了
-》選擇並安裝-》好安裝好後咱們能夠查看「引用」下面有了以下變化
而且project.json文件中自動添加了依賴項:
好了到咱們的TaskCore.Test項目中就可使用Task.Plugin包裏面的方法很類等信息了;
使用TaskCore.MainForm:
由上面的操做TaskCore.Test項目已經安裝了Task.Plugin包,那麼咱們在項目中分別建立3個子類並繼承自Task.Plugin包的父類TPlugin並重寫方法TPlugin_Load(),對應文件名稱分別爲:BlogsObj.cs,BlogsObj01.cs,BlogsObj02.cs,分別添加入下代碼內容:
BlogsObj.cs:
1 namespace TaskCore.Test 2 { 3 // This project can output the Class library as a NuGet Package. 4 // To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build". 5 public class BlogsObj : TPlugin 6 { 7 public BlogsObj() 8 { 9 10 } 11 12 public override void TPlugin_Load() 13 { 14 var sbLog = new StringBuilder(string.Empty); 15 try 16 { 17 sbLog.Append($"這裏是BlogsObj,獲取配置文件:{this.XmlConfig.Name}"); 18 19 //代碼塊 20 // 21 22 new WriteLog()._WriteLog($"{DateTime.Now}測試引用nuget包"); 23 24 } 25 catch (Exception ex) 26 { 27 sbLog.Append($"異常信息:{ex.Message}"); 28 } 29 finally 30 { 31 32 PublicClass._WriteLog(sbLog.ToString(), this.XmlConfig.Name); 33 } 34 } 35 } 36 }
BlogsObj01.cs:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using TaskCore.Plugin; 7 8 namespace TaskCore.Test 9 { 10 // This project can output the Class library as a NuGet Package. 11 // To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build". 12 public class BlogsObj01 : TPlugin 13 { 14 public BlogsObj01() 15 { 16 17 } 18 19 public override void TPlugin_Load() 20 { 21 var sbLog = new StringBuilder(string.Empty); 22 try 23 { 24 sbLog.Append($"這裏是BlogsObj01,獲取配置文件:{this.XmlConfig.Name}"); 25 26 //代碼塊 27 // 28 } 29 catch (Exception ex) 30 { 31 sbLog.Append($"異常信息:{ex.Message}"); 32 } 33 finally 34 { 35 //Console.WriteLine($"這裏是Blogs,獲取配置文件:{this.XmlConfig.Name}"); 36 PublicClass._WriteLog(sbLog.ToString(), this.XmlConfig.Name); 37 } 38 } 39 } 40 }
BlogsObj02.cs:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Threading.Tasks; 5 using TaskCore.Plugin; 6 7 namespace TaskCore.Test 8 { 9 // This project can output the Class library as a NuGet Package. 10 // To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build". 11 public class BlogsObj02 : TPlugin 12 { 13 public BlogsObj02() 14 { 15 16 } 17 18 public override void TPlugin_Load() 19 { 20 //Console.WriteLine($"這裏是Blogs,獲取配置文件:{this.XmlConfig.Name}"); 21 PublicClass._WriteLog($"這裏是BlogsObj02,獲取配置文件:{this.XmlConfig.Name}", this.XmlConfig.Name); 22 } 23 } 24 }
好了測試代碼寫完,咋們生成一下,而後把這個TaskCore.Test.dll拷貝到TaskCore.MainForm運行包中,還須要在PluginXml文件夾中分別建立繼承TPlugin的子類的配置文件對應的截圖如(注:這裏xml配置文件名稱必須和子類名稱同樣):
配置文件內容如BlogsObj.xml:
1 <!-- 2 1.xml配置模板 3 2.utf-8文件 4 3.複製到程序根目錄下面PluginXml文件夾下 5 4.每一個任務建議建立和程序dll名稱相同xml配置文件 6 --> 7 <TaskMain> 8 <!--固定:執行任務時間計時器(分鐘)--> 9 <Timer>1</Timer> 10 <!--固定:任務名稱--> 11 <Name>獲取博客信息</Name> 12 <!--固定:帳號--> 13 <UserName></UserName> 14 <!--固定:密碼--> 15 <UserPwd></UserPwd> 16 <!--固定:key--> 17 <ApiKey></ApiKey> 18 <!--固定:key--> 19 <ApiUrl></ApiUrl> 20 <!--固定:是否關閉任務 1:是 0:否--> 21 <CloseTask>0</CloseTask> 22 23 <!--固定:描述--> 24 <Des>獲取博客信息</Des> 25 <!--自定義:其餘配置信息--> 26 <Other> 27 <ShenNiuBuXing3>神牛步行3</ShenNiuBuXing3> 28 </Other> 29 </TaskMain>
最後在CrossFiles.xml配置文件中添加TaskCore.Test.dll文件名稱如:
1 <!-- 2 CrossFiles指定對應任務的dll文件,必須存在的文件 3 --> 4 <TaskMain> 5 <File>TaskCore.Test.dll</File> 6 </TaskMain>
好了完成了,咱們在windows開發環境上運行看下效果圖:
到這裏咱們來簡單總結下怎麼使用TaskCore.MainForm插件,在本身項目中安裝TaskCore.Plugin的nuget包-》重寫父類TPlugin的TPlugin_Load()方法-》生成本身的項目,拷貝項目的dll到TaskCore.MainForm運行包中-》在運行包中PluginXml文件夾中增長任務子類相同類名的xml文件並配置如上的配置信息-》增長CrossFiles.xml中的任務dll文件配置-》使用命令 dotnet TaskCore.MainForm.dll 運行服務插件,挺簡單的吧
. win7和ubuntu16.04運行TaskCore.MainForm的兩種方式和測試截圖(也可認爲.netcore項目在win7和ubuntu系統運行的兩種方式)
因爲環境影響,這裏跨平臺運行測試我只測試win7和ubuntu16.04,其餘系統的發佈測試但願朋友們在使用過程當中獲得結果告知我下謝謝;先來說在win7中運行:
1. 安裝了netcore sdk環境的發佈運行
安裝了sdk後直接能夠在cmd命令中 dotnet TaskCore.MainForm.dll 來運行服務,開篇上面講解的示例都是在安裝了sdk後的截圖,服務運行所須要的文件如圖:
就只有這些文件(固然程序須要的某些平臺依賴項使用的是安裝的sdk中的文件,因此看起來不多實際應該包含netcore sdk裏面的文件才能運行),經過命令運行的效果圖:
2. 未安裝netcore sdk環境的發佈運行
在爲安裝sdk平臺上系統上運行纔是重點,這樣才能夠說是跨平臺;首先,爲了更好看效果咱們複製一份如圖的兩個文件到TaskCore.MainForm01文件夾中:
沒錯,只須要這兩個文件,而後咱們須要修改project.json文件的內容以下注釋的地方:
1 { 2 "version": "1.0.0-*", 3 "buildOptions": { 4 "emitEntryPoint": true 5 }, 6 7 "dependencies": { 8 "Microsoft.NETCore.App": { 9 //"type": "platform", 跨平臺發佈須要註釋 10 "version": "1.0.0" 11 }, 12 "System.IO.FileSystem": "4.0.1", 13 "System.Reflection": "4.1.0", 14 "System.Text.Encoding.CodePages": "4.0.1", 15 "System.Threading.Timer": "4.0.1", 16 "System.Xml.XDocument": "4.0.11", 17 "TaskCore.Plugin": "1.0.0" 18 }, 19 20 "frameworks": { 21 "netcoreapp1.0": { 22 "imports": "dnxcore50" 23 } 24 }, 25 //跨平臺發佈須要添加以下節點 26 "runtimes": { 27 "ubuntu.16.04-x64": { }, //運行在ubuntu.16.04的64位系統 28 "win7-x64": { } //運行在win7的64位系統 29 } 30 }
而後使用cmd分別錄入並回車運行指令 dotnet restore 此時TaskCore.MainForm01文件夾中會自動生成一個project.lock.json文件(你們注意看下),而後再錄入指令 dotnet publish -r win7-x64 ,能夠看到命令窗信息如:
就表示成功了,而且有返回生成運行文件的路徑,咱們按照路徑找到生成的文件publish文件夾,裏面沒有PluginXml配置文件夾和配置文件和測試項目TaskCore.Test.dll,咱們爲了方便直接複製上面配置好的配置文件到publish文件夾中以下截圖就是生成的發佈文件:
沒錯TaskCore.MainForm01.exe這個就是自動生成的運行文件,而後咱們雙擊運行效果圖:
運行成功了,有朋友會問您以前系統不是安裝了sdk麼,這種測試能算麼,我想說的是這個我經過QQ發給qq羣裏面的朋友@南宮亦琦(不要怪我貼出了您的暱稱)測試過了,她沒有安裝過sdk的;
ubuntu16.04運行:
1. 安裝了netcore sdk環境的發佈運行
首先,咱們須要把在win7上生成的項目複製到ubuntu系統磁盤中(咱們使用上面配置好的TaskCore.MainForm包),我這裏採用共享目錄的方式把文件拷貝到ubuntu系統磁盤上,如圖:
而後,鼠標右鍵點擊空白地方,選擇「在終端打開」,而後在窗體中錄入以下指令 dotnet TaskCore.MainForm.dll ,能看到以下運行起的結果:
這個命令方式是否是很上面win7上的方式很相同,原本就是同樣的,只要安裝了.netcore sdk這種方式幾乎能夠共用
2. 未安裝netcore sdk環境的發佈運行
不安裝sdk環境運行纔是咋們須要關注的,下面就來看下怎麼生成再ubuntu系統上能運行的文件;咱們複製一份上面的TaskCore.MainForm01項目到TaskCore.MainForm02中來測試,因爲以前咱們在講生成win7執行文件時候,執行了命令 dotnet restore 和 dotnet publish -r win7-x64 命令因此文件中有project.lock和bin文件夾,爲了測試咱們須要刪除掉部分文件,只剩下如圖文件,這裏須要注意的是以前已經配置過project.xml咱們無需在修改了:
而後,分別執行和生成win7運行文件幾乎相同的命令 dotnet restore 和 dotnet publish -r ubuntu.16.04-x64 不一樣之處在於生成的文件存放的位置不一樣和使用的運行環境不一樣,運行結果如圖:
publish文件夾中的文件就是在ubuntu系統執行的文件,而後咱們須要把任務配置文件夾PluginXml和測試項目TaskCore.Test.dll複製到該目錄中,再來咋們經過共享吧TaskCore.MainForm02目錄中的publish複製到ubuntu中;而後咱們須要把TaskCore.MainForm02可執行文件設置下權限,鼠標右鍵點擊TaskCore.MainForm02可執行文件,選擇「屬性」,再選擇「權限」選項卡,勾選「容許做爲程序執行」,如圖:
而後,咱們右鍵文件夾中空白處,選擇「在終端打開」,再執行以下命令 ./TaskCore.MainForm02 ,最後看運行效果圖:
好了,發佈在ubuntu系統上執行文件和運行的步奏就這些,幾乎和win7上相同
. 框架代碼解讀及感悟
怎麼使用跨平臺TaskCore.MainForm任務框架講解完了,下面來具體看下主要代碼Program.cs文件中:
1 namespace TaskCore.MainForm 2 { 3 /// <summary> 4 /// author 神牛步行3 5 /// contact 841202396@qq.com 6 /// des TaskCore.MainForm跨平臺插件由神牛步行3提供 7 /// </summary> 8 public class Program 9 { 10 11 private static Dictionary<string, MoAssembly> dicTasks = new Dictionary<string, MoAssembly>(); 12 13 public static void Main(string[] args) 14 { 15 //註冊編碼,防止亂碼 16 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 17 18 //初始化程序集文件 19 _Init(); 20 21 //是否繼續開啓任務,默認沒有待執行任務,不提示 22 if (dicTasks.Count <= 0) { _LoopAlert("是否退出?(Y/N)"); return; } 23 _LoopAlert("是否開始執行任務?(Y / N)"); 24 25 //執行任務 26 foreach (var item in dicTasks.Values) 27 { 28 //使用Task防止異常後相互影響 29 Task.Run(() => 30 { 31 try 32 { 33 34 //建立任務對象 35 var tp = item.Asm.CreateInstance(item.FullName) as TPlugin; 36 if (!string.IsNullOrEmpty(tp.XmlConfig.TpError)) { _Alert($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm")}:{tp.XmlConfig.Name} - 異常信息:{tp.XmlConfig.TpError}"); } 37 else 38 { 39 40 //timer定時器 41 var timer = new Timer((param) => 42 { 43 var msg = $"{DateTime.Now.ToString("yyyy/MM/dd HH:mm")}:{tp.XmlConfig.Name}"; 44 try 45 { 46 var tpObj = param as TPlugin; 47 //是否關閉暫停任務 48 if (tpObj.XmlConfig.CloseTask) { return; } 49 _Alert($"{msg} - 開始執行...{tp.XmlConfig.Timer}分鐘一次"); 50 //任務入口 51 tpObj.TPlugin_Load(); 52 } 53 catch (Exception ex) { _Alert($"{msg} - 異常信息:{ex.Message}"); } 54 }, tp, 0, 1000 * 60 * tp.XmlConfig.Timer); 55 } 56 57 } 58 catch (Exception ex) 59 { 60 _Alert($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm")}:{item.Name} - 異常信息:{ex.Message}"); 61 } 62 }); 63 } 64 _LoopAlert("正在監控執行的任務,是否退出?(Y / N)"); 65 } 66 67 /// <summary> 68 /// 初始化程序集文件 69 /// </summary> 70 private static void _Init() 71 { 72 try 73 { 74 75 _Alert("初始化任務中..."); 76 //獲取文件 77 var files = PublicClass._GetPluginFile(""); 78 if (files.Length <= 0) { _Alert("未能找到可用的程序集,請檢查配置"); return; } 79 80 //讀取任務文件 81 _Alert("讀取CrossFiles.xml配置中..."); 82 var baseAddr = Path.Combine(Directory.GetCurrentDirectory(), "PluginXml", "CrossFiles.xml"); 83 var doc = XDocument.Load(baseAddr); 84 var fileables = files.AsEnumerable(); 85 var taskFiles = new List<FileInfo>(); 86 foreach (var item in doc.Root.Nodes()) 87 { 88 var crossFile = item.ToString().ToUpper(); 89 var choiceFiles = fileables.Where(b => crossFile.Contains(b.Name.ToUpper())); 90 if (!choiceFiles.Any()) { continue; } 91 92 taskFiles.AddRange(choiceFiles); 93 } 94 95 //展現文件信息 96 _Alert($"待遍歷{taskFiles.Count}個文件信息..."); 97 foreach (var item in taskFiles.OrderBy(b => b.CreationTime)) 98 { 99 var asmName = new AssemblyName($"{item.Name.Replace(".dll", "")}"); 100 Assembly sm = Assembly.Load(asmName); 101 if (sm == null) { continue; } 102 var ts = sm.GetTypes(); 103 //判斷特定的任務類,加入任務dic 104 foreach (var t in ts.Where(b => b.Name != "TPlugin" && b.GetMethod("TPlugin_Load") != null)) 105 { 106 107 dicTasks.Add( 108 t.FullName, 109 new MoAssembly 110 { 111 Asm = sm, 112 FullName = t.FullName, 113 Name = t.Name 114 }); 115 } 116 } 117 _Alert($"獲取待執行任務量:{dicTasks.Count}個"); 118 } 119 catch (Exception ex) 120 { 121 _Alert($"異常信息:{ ex.Message}"); 122 } 123 } 124 125 /// <summary> 126 /// 消息提醒 127 /// </summary> 128 /// <param name="msg">提示信息</param> 129 /// <param name="isReadLine">是否須要用戶輸入指令</param> 130 /// <returns>用戶錄入的指令</returns> 131 private static string _Alert(string msg = "神牛步行3-消息提醒", bool isReadLine = false) 132 { 133 Console.WriteLine(msg); 134 if (isReadLine) { return Console.ReadLine(); } 135 return ""; 136 } 137 138 private static void _LoopAlert(string msg = "是否開始執行任務?(Y/N)") 139 { 140 do 141 { 142 var readKey = _Alert(msg, true); 143 if (readKey.ToUpper().Contains("Y")) { break; } 144 } while (true); 145 } 146 } 147 148 public class MoAssembly 149 { 150 public Assembly Asm { get; set; } 151 public string FullName { get; set; } 152 153 public string Name { get; set; } 154 } 155 }
TPlugin.cs文件中代碼:
1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using System.Threading.Tasks; 6 using System.Xml.Linq; 7 8 namespace TaskCore.Plugin 9 { 10 /// <summary> 11 /// 插件基類 12 /// </summary> 13 public class TPlugin : IDisposable 14 { 15 16 public TPlugin() 17 { 18 19 XmlConfig = _InitConfig(); 20 } 21 22 #region 初始化Xml配置文件 _InitConfig +XmlConfig 23 24 /// <summary> 25 /// xml配置信息 26 /// </summary> 27 public XmlConfig XmlConfig; 28 29 30 /// <summary> 31 /// 初始化配置信息 32 /// </summary> 33 /// <param name="configPath">配置文件對應路徑</param> 34 /// <returns></returns> 35 public virtual XmlConfig _InitConfig(string configPath = "") 36 { 37 XmlConfig config = new XmlConfig(); 38 config.Timer = 1; 39 config.Name = this.GetType().Name; 40 try 41 { 42 43 if (string.IsNullOrEmpty(configPath)) 44 { 45 46 //默認各個dllXml配置 47 var defaultConfigFolder = "PluginXml"; 48 var baseAddr = Directory.GetCurrentDirectory(); 49 configPath = Path.Combine(baseAddr, defaultConfigFolder, config.Name + ".xml"); 50 } 51 52 var doc = XDocument.Load(configPath); 53 config.doc = doc; 54 var taskMain = doc.Root; 55 56 config.Timer = Convert.ToInt32(taskMain.Element(XName.Get("Timer", "")).Value); 57 config.Name = taskMain.Element(XName.Get("Name", "")).Value; 58 config.Des = taskMain.Element(XName.Get("Des", "")).Value; 59 60 config.UserName = taskMain.Element(XName.Get("UserName", "")).Value; 61 config.UserPwd = taskMain.Element(XName.Get("UserPwd", "")).Value; 62 config.ApiKey = taskMain.Element(XName.Get("ApiKey", "")).Value; 63 config.ApiUrl = taskMain.Element(XName.Get("ApiUrl", "")).Value; 64 config.CloseTask = taskMain.Element(XName.Get("CloseTask", "")).Value == "1"; 65 66 } 67 catch (Exception ex) 68 { 69 config.TpError = ex.Message; 70 PublicClass._WriteLog($"{config.Name}初始化配置信息異常:{ex.Message}", "BaseLog"); 71 throw new Exception(ex.Message); 72 } 73 return config; 74 } 75 #endregion 76 77 #region 初始化-開始加載 _Load 78 79 /// <summary> 80 /// 初始化-開始起 81 /// </summary> 82 public virtual void TPlugin_Load() 83 { 84 85 PublicClass._WriteLog("測試"); 86 } 87 88 #endregion 89 90 #region 釋放資源 91 92 public void Dispose() 93 { 94 95 GC.SuppressFinalize(this);//不須要再調用本對象的Finalize方法 96 } 97 98 public virtual void Dispose(Action action) 99 { 100 101 action(); 102 } 103 104 #endregion 105 } 106 107 #region 配置文件 XmlConfig 108 109 public class XmlConfig 110 { 111 public XmlConfig() 112 { 113 114 } 115 116 /// <summary> 117 /// 定製器時間(分鐘) 118 /// </summary> 119 public int Timer { get; set; } 120 121 /// <summary> 122 /// 運行名稱 123 /// </summary> 124 public string Name { get; set; } 125 126 /// <summary> 127 /// 描述(第一次獲取dll描述,後面獲取xml配置文件描述) 128 /// </summary> 129 public string Des { get; set; } 130 131 /// <summary> 132 /// 接口帳號 133 /// </summary> 134 public string UserName { get; set; } 135 136 /// <summary> 137 /// 接口密碼 138 /// </summary> 139 public string UserPwd { get; set; } 140 141 /// <summary> 142 /// 接口祕鑰 143 /// </summary> 144 public string ApiKey { get; set; } 145 146 /// <summary> 147 /// 接口地址 148 /// </summary> 149 public string ApiUrl { get; set; } 150 151 /// <summary> 152 /// 是否關閉任務 153 /// </summary> 154 public bool CloseTask { get; set; } 155 156 /// <summary> 157 /// 插件中錯誤 158 /// </summary> 159 public string TpError { get; set; } 160 161 162 /// <summary> 163 /// xml信息 164 /// </summary> 165 public XDocument doc { get; set; } 166 } 167 168 #endregion 169 }
具體的說明和邏輯處理代碼中都有註釋,各位能夠詳細看下;這裏要訴說的是該框架主要原理是動態加載任務dll來建立對象,netcore的程序集類Assembly不像framework裏面的Assembly同樣那麼多能夠用方法,我這裏用的 Assembly.Load() ,netcore只能加載當前系統根目錄的dll(這裏我花了幾個小時測試,有不一樣結果的朋友,請及時聯繫我謝謝),框架使用 Task.Run() 方法建立不一樣任務,實現並行執行的效果,而且各個容易出錯地方使用try...catch來容錯,避免了某個子任務異常後,致使框架所有中斷運行,我的以爲其實仍是不錯的是吧;
下面給出幾個不一樣環境下的壓縮包,以供使用和參考: