Open-source cross-platform running service plug-in TaskCore. MainForm,

Source: Internet
Author: User

Open-source cross-platform running service plug-in TaskCore. MainForm,

This is a cross-platform service plug-in-TaskCore. mainForm. This framework is used. according to netcore, netcore now supports running on many system platforms. mainForm has been improved to a cross-platform service for mutual use and communication. Originally, this article will share nginx + iis + redis + Task. mainForm will be used in subsequent articles on building the distributed architecture. netcore defines a service plug-in and cross-platform testing. After testing, I am excited and have a headache. If you don't want to talk about it next time, I will share it with you later. Now, I hope you can enjoy the following content:

. Framework structure introduction and operation

. How to generate the nuget package and use the open-source framework TaskCore. MainForm

. Win7 and ubuntu16.04 run TaskCore. MainForm in two ways and test (you can also think that the. netcore project runs in win7 and ubuntu)

. Framework Code interpretation and Sentiment

Let's share it one step at a time:

. Framework structure introduction and operation

First, let's take a look at the project directory structure of the project source code.

The structure should seem clear enough, and there are few source code files, but it does realize the dynamic loading of Assembly dll to execute the task. The corresponding execution will be given later. Let's take a look at TaskCore. mainForm project files in the Bin folder generated after vs2015

If yes. for the netcore sdk, you only need the above files to run the plug-in. Then, run the following command dotnet TaskCore on the win7 system that has installed the core sdk. mainForm. dll to see the effect:

Yes, this is the plug-in running, because. netcore currently does not provide skin interface effects similar to winform, and all programs can only be run across platforms through the command line.

. How to generate the nuget package and use TaskCore. MainForm

First, we need to clarify that the Service is composed of two parts (TaskCore. mainForm and TaskCore. plugin); TaskCore. mainForm is mainly used to run programs, TaskCore. plugin is used as the parent class plug-in to be inherited by subtasks. When we download TaskCore. after MainForm runs the package (2 structure), what we need to do is inherit TaskCore. plugin. the TPlugin class in dl is used to override the content of the task. Therefore, we create a new project named TaskCore. test. Then, we can directly add TaskCore through the reference function of vs2015. taskCore in the MainForm running package. plugin. dl reference. An error is prompted at this time:

The error indicates that the netcore dll version cannot be loaded. Therefore, adding the dll dependency directly in the reference method of the vs project does not work. You need to use nuget to add the dependency package (. currently, netcore can only use nuget to install dependencies on class libraries. Note that. the plug-in project uses the dotnet pack command to generate the nuget package so that I can use TaskCore. in the Test project;

How to generate the nuget package (the process and download of the dotnet command in win7 system ):

Right-click the class library project you want to package in vs and select "Open folder in resource manager"-to go to the root directory of your class library, then, return to the upper-level folder in the root directory of the class library. Press and hold the "shift" key and right-click the project file to package the class library (I am TaskCore here. in the "Plugin folder)-" select "Open command form here", and then enter the cmd command form. Of course, some friends directly prefer cmd to find the corresponding disk, anyway, I think the first method is faster (different people choose different ones). Let's take a look at the operation below:

As you can see, the nupkg file is generated using commands. This file is the TaskCore that needs to be downloaded and installed in the project. plugin plug-in package; Next we will go to TaskCore. to install the plug-in the Test project, right-click TaskCore. in the Plugin project, select "Reference"-"manage nuget packages"-"and select the icon in the upper right corner.

-"Select" Nuget Package Manager "-" package source "-"

-"And then select the newly created package source. The settings are as follows:

Here "source (S) "The specified local path is the disk of the nupkg file we just generated (of course, I am here to copy the file generated by the pack command to the MyNugPackage folder for testing) -and then click "OK" button-and then return

Select our package source MyNugPackage-and click here to view the nuget package we created.

-Select and install-after installation, we can view the following changes under the "Reference ":

In addition, dependency items are automatically added to the project. json file:

Now, in our TaskCore. Test Project, you can use the methods in the Task. Plugin package to provide class information;

Use TaskCore. MainForm:

The preceding operation TaskCore. task has been installed in the Test project. plugin package, we create three sub-classes in the project and inherit from the Task. the parent class TPlugin of the Plugin package and the override method TPlugin_Load (). The corresponding file names are BlogsObj. cs, BlogsObj01.cs, and BlogsObj02.cs, respectively Add the following code content:

BlogsObj. cs:

Namespace TaskCore. test {// This project can output the Class library as a NuGet Package. // To enable this option, right-click on the project and select the Properties menu item. in the Build tab select "Produce outputs on build ". public class BlogsObj: TPlugin {public BlogsObj () {} public override void TPlugin_Load () {var sbLog = new StringBuilder (string. empty); try {sbLog. append ($ "here is BlogsObj, get the configuration file: {this. xmlConfig. name} "); // code block // new WriteLog (). _ WriteLog ($ "{DateTime. now} test reference nuget package ");} catch (Exception ex) {sbLog. append ($ "exception message: {ex. message} ") ;}finally {PublicClass. _ WriteLog (sbLog. toString (), this. xmlConfig. name );}}}}

BlogsObj01.cs:

Using System; using System. collections. generic; using System. linq; using System. text; using System. threading. tasks; using TaskCore. plugin; namespace TaskCore. test {// This project can output the Class library as a NuGet Package. // To enable this option, right-click on the project and select the Properties menu item. in the Build tab select "Produce outputs on build ". public class BlogsObj01: TPlugin {public BlogsObj01 () {} public override void TPlugin_Load () {var sbLog = new StringBuilder (string. empty); try {sbLog. append ($ "here is BlogsObj01, get the configuration file: {this. xmlConfig. name} "); // code block //} catch (Exception ex) {sbLog. append ($ "exception message: {ex. message} ") ;}finally {// Console. writeLine ($ "here is Blogs, get the configuration file: {this. xmlConfig. name} "); PublicClass. _ WriteLog (sbLog. toString (), this. xmlConfig. name );}}}}

BlogsObj02.cs:

Using System; using System. collections. generic; using System. linq; using System. threading. tasks; using TaskCore. plugin; namespace TaskCore. test {// This project can output the Class library as a NuGet Package. // To enable this option, right-click on the project and select the Properties menu item. in the Build tab select "Produce outputs on build ". public class BlogsObj02: TPlugin {public BlogsObj02 () {} public override void TPlugin_Load () {// Console. writeLine ($ "here is Blogs, get the configuration file: {this. xmlConfig. name} "); PublicClass. _ WriteLog ($ "BlogsObj02 here, get the configuration file: {this. xmlConfig. name} ", this. xmlConfig. name );}}}

After the test code is completed, we will generate the TaskCore. test. dll copy to TaskCore. in the MainForm running package, you also need to create the configuration file corresponding to the subclass that inherits TPlugin in the PluginXml folder (Note: The xml configuration file name must be the same as the subclass name here ):

Configuration file content such as BlogsObj. xml:

<! -- 1. xml configuration template 2. UTF-8 file 3. copy to the PluginXml folder under the root directory of the program. 4. we recommend that you create an xml configuration file with the same name as the program dll for each task --> <TaskMain> <! -- Fixed: task execution time Timer (minutes) --> <Timer> 1 </Timer> <! -- Fixed: Task Name --> <Name> Get blog Information </Name> <! -- Fixed: account --> <UserName> </UserName> <! -- Fixed: Password --> <UserPwd> </UserPwd> <! -- Fixed: key --> <ApiKey> </ApiKey> <! -- Fixed: key --> <ApiUrl> </ApiUrl> <! -- Fixed: whether to close Task 1: 0: No --> <CloseTask> 0 </CloseTask> <! -- Fixed: description --> <Des> Get blog Information </Des> <! -- Custom: Other configuration information --> <Other> <ShenNiuBuXing3> ShenNiuBuXing3 </ShenNiuBuXing3> </Other> </TaskMain>

Finally, add the TaskCore. Test. dll file name to the CrossFiles. xml configuration file, for example:

<! -- CrossFiles specifies the dll File of the corresponding task, which must exist --> <TaskMain> <File> TaskCore. Test. dll </File> </TaskMain>

Now, let's run it in the windows development environment. Let's see:

Here we will briefly summarize how to use TaskCore. mainForm plug-in. Install TaskCore in your project. in the nuget package of Plugin, rewrite the TPlugin_Load () method of the parent class TPlugin to generate your own project and copy the dll of the project to TaskCore. mainForm running package-Add the xml file with the same class name as the task subclass in the PluginXml folder of the running package and configure the above configuration information-add CrossFiles. configure the task dll file in xml-use the command dotnet TaskCore. mainForm. it's quite simple to run the service plug-in using dll.

. Win7 and ubuntu16.04 run TaskCore. MainForm in two ways and test (you can also think that the. netcore project runs in win7 and ubuntu)

Due to environmental impact, I only test Windows 7 and ubuntu16.04 for cross-platform testing. I hope my friends can get the results during the release test of other systems and tell me Thank you. Let's first run the test in Windows 7:

1. Release and run the netcore sdk Environment

After installing the sdk, you can run the service directly in the cmd command dotnet TaskCore. MainForm. dll. The examples described above are all after the sdk is installed and the files required for Service Running

Only these files are needed (of course, some platform dependencies required by the program use files in the installed sdk, so it seems that files in the netcore sdk should be rarely included ), run the following command:

2. Release and run of netcore sdk environment Not Installed

It is important to install the sdk on the system, so that it can be said to be cross-platform. First, we copy two files to the TaskCore. MainForm01 folder for better results:

Yes, we only need these two files. Then we need to modify the content of the project. json file as follows:

{"Version": "1.0.0-*", "buildOptions": {"emitEntryPoint": true}, "dependencies": {"Microsoft. NETCore. app ": {//" type ":" platform ", comment" version ":" 1.0.0 "}," System. IO. fileSystem ":" 4.0.1 "," System. reflection ":" 4.1.0 "," System. text. encoding. codePages ":" 4.0.1 "," System. threading. timer ":" 4.0.1 "," System. xml. XDocument ":" 4.0.11 "," TaskCore. plugin ":" 1.0.0 "}," frameworks ": {" netcoreapp1.0 ": {" imports ":" dnxcore50 "}}, // Add the following node" runtimes "for cross-platform publishing ": {"ubuntu.16.04-x64" :{}, // 64-bit system running on ubuntu.16.04 "win7-x64" :{}// 64-bit system running on win7 }}

Then use cmd to enter and press enter to run the command dotnet restore at this time TaskCore. A project is automatically generated in the MainForm01 folder. lock. json file (please note), and then enter the command dotnet publish-r win7-x64, you can see the command window information such:

It indicates that the task is successful, and the path of the generated running file is returned. We can find the generated file publish folder by path, without the PluginXml configuration folder and configuration file and the test project TaskCore. test. dll. For convenience, copy the configuration file configured above to the publish folder as follows:

Taskcore.mainform01.exe is the automatically generated running file, and then we double-click to run:

If the test succeeds, a friend may ask if the system has installed the sdk before. Can this test be considered, I want to talk about this. I sent it to a friend in the QQ Group @ Nangong Yiqi (don't blame me for posting your nickname) and tested it. She hasn't installed the sdk;

Ubuntu16.04 run:

1. Release and run the netcore sdk Environment

First, we need to copy the project generated on win7 to the ubuntu system disk (we use the TaskCore configured above. mainForm package), I use the shared directory method to copy files to the ubuntu system disk,

Right-click a blank area, select "open in terminal", and enter the following command dotnet TaskCore. MainForm. dll in the form. The following running result is displayed:

This command method is not the same as that on win7. It is the same as it was previously. As long as the. netcore sdk is installed, this method can be almost shared.

2. Release and run of netcore sdk environment Not Installed

We need to pay attention to running the sdk environment without installing it. Let's take a look at how to generate the files that can be run on the ubuntu system. We will copy the TaskCore. mainForm01 project to TaskCore. mainForm02 to test, because we previously talked about generating win7 execution file, execute the command dotnet restore and dotnet publish-r win7-x64 command so there is a project in the file. lock and bin folders. In order to test, we need to delete some files, only the files are left. Note that the project has been configured before. we do not need to modify the xml:

Then, execute and generate the command dotnet restore and dotnet publish-r ubuntu.16.04-x64, respectively, because the generated file is stored in different locations and the running environment is different, running result

The files in the publish folder are the files executed in the ubuntu system. Then we need to configure the PluginXml folder and the test project TaskCore. test. dll is copied to this directory. Then, share TaskCore. copy publish in the MainForm02 directory to ubuntu. Then we need to copy TaskCore. mainForm02 executable file setting permissions, right-click TaskCore. mainForm02 executable file, select "properties", then select the "Permissions" tab, and select "allow execution as a program ",

Then, right-click the blank area in the folder, select "open on terminal", and then execute the following command./TaskCore. MainForm02. Finally, let's see the run:

All right, these are the execution files released on ubuntu and the running steps, which are almost the same as those on win7.

. Framework Code interpretation and Sentiment

The cross-platform TaskCore. MainForm task framework has been explained. The following describes the main code in the Program. cs file:

Namespace TaskCore. mainForm {// <summary> /// author walking 3 // contact 841202396@qq.com // des TaskCore. mainForm cross-platform plug-in is provided by shenniu walk 3 /// </summary> public class Program {private static Dictionary <string, MoAssembly> dicTasks = new Dictionary <string, MoAssembly> (); public static void Main (string [] args) {// register the Encoding to prevent garbled Encoding. registerProvider (CodePagesEncodingProvider. instance); // initialize the Assembly file _ Init (); // whether If (dicTasks. Count <= 0) {_ LoopAlert ("exit? (Y/N) "); return;} _ LoopAlert (" start to execute the task? (Y/N) "); // execute the task foreach (var item in dicTasks. values) {// use a Task to prevent tasks from being affected after an exception. run () => {try {// create the task object var tp = item. asm. createInstance (item. fullName) as TPlugin; if (! String. isNullOrEmpty (tp. xmlConfig. tpError) {_ Alert ($ "{DateTime. now. toString ("yyyy/MM/dd HH: mm") }:{ tp. xmlConfig. name}-exception information: {tp. xmlConfig. tpError} ");} else {// timer var Timer = new timer (param) =>{ var msg =$" {DateTime. now. toString ("yyyy/MM/dd HH: mm") }:{ tp. xmlConfig. name} "; try {var tpObj = param as TPlugin; // whether to disable the pause task if (tpObj. xmlConfig. closeTask) {return;} _ Alert ($ "{msg}-start execution... {t P. xmlConfig. timer} Once every minute "); // task entry tpObj. TPlugin_Load ();} catch (Exception ex) {_ Alert ($ "{msg}-Exception information: {ex. message} ") ;}}, tp, 0, 1000*60 * tp. xmlConfig. timer) ;}} catch (Exception ex) {_ Alert ($ "{DateTime. now. toString ("yyyy/MM/dd HH: mm") }:{ item. name}-exception information: {ex. message} ") ;}}) ;}_ LoopAlert (" the task being monitored. Are you sure you want to exit? (Y/N) ");} // <summary> // initialize the Assembly file // </summary> private static void _ Init () {try {_ Alert ("Initializing task... "); // get the file var files = PublicClass. _ GetPluginFile (""); if (files. length <= 0) {_ Alert ("the available assembly cannot be found, please check the configuration"); return;} // read the task file _ Alert ("read CrossFiles. configuring xml... "); var baseAddr = Path. combine (Directory. getCurrentDirectory (), "PluginXml", "CrossFiles. xml "); var doc = XDocument. load (baseAddr); var Fileables = files. asEnumerable (); var taskFiles = new List <FileInfo> (); foreach (var item in doc. root. nodes () {var crossFile = item. toString (). toUpper (); var choiceFiles = fileables. where (B => crossFile. contains (B. name. toUpper (); if (! ChoiceFiles. any () {continue;} taskFiles. addRange (choiceFiles);} // displays the File Information _ Alert ($ "to be traversed {taskFiles. count} file information... "); foreach (var item in taskFiles. orderBy (B => B. creationTime) {var asmName = new AssemblyName ($ "{item. name. replace (". dll "," ")}"); Assembly sm = Assembly. load (asmName); if (sm = null) {continue;} var ts = sm. getTypes (); // identifies a specific task class, and adds the task dic foreach (var t in ts. where (B => B. name! = "TPlugin" & B. GetMethod ("TPlugin_Load ")! = Null) {dicTasks. add (t. fullName, new MoAssembly {Asm = sm, FullName = t. fullName, Name = t. name}) ;}}_ Alert ($ "get the number of tasks to be executed: {dicTasks. count} ");} catch (Exception ex) {_ Alert ($" Exception information: {ex. message }");}} /// <summary> /// message reminder /// </summary> /// <param name = "msg"> message </param> /// <param name = "isReadLine"> whether the user needs to input the command </param> // <returns> User input command </returns> private static string _ Alert (string msg = "Shenniu walking 3-message reminder", bool isReadLine = false) {Console. writeLine (msg); if (isReadLine) {return Console. readLine () ;}return "" ;}private static void _ LoopAlert (string msg = "start to execute the task? (Y/N) ") {do {var readKey = _ Alert (msg, true); if (readKey. toUpper (). contains ("Y") {break ;}} while (true) ;}} public class MoAssembly {public Assembly Asm {get; set ;} public string FullName {get; set ;}public string Name {get; set ;}}}

Code in the TPlugin. cs file:

Using System; using System. collections. generic; using System. IO; using System. linq; using System. threading. tasks; using System. xml. linq; namespace TaskCore. plugin {// <summary> // plug-in base class /// </summary> public class TPlugin: IDisposable {public TPlugin () {XmlConfig = _ InitConfig ();} # region initialize the Xml configuration file _ InitConfig + XmlConfig // <summary> // xml configuration information /// </summary> public XmlConfig; /// <summary> /// Initialization Configuration Information /// </summary> /// <param name = "configPath"> path of the configuration file </param> // /<returns> </returns> public virtual XmlConfig _ InitConfig (string configPath = "") {XmlConfig config = new XmlConfig (); config. timer = 1; config. name = this. getType (). name; try {if (string. isNullOrEmpty (configPath) {// default for each dllXml configuration var defaultConfigFolder = "PluginXml"; var baseAddr = Directory. getCurrentDirectory (); configPath = Path. combine (baseAddr, defaultConfigFolder, config. name + ". xml ");} var doc = XDocument. load (configPath); config.doc = doc; var taskMain = doc. root; config. timer = Convert. toInt32 (taskMain. element (XName. get ("Timer ","")). value); config. name = taskMain. element (XName. get ("Name ","")). value; config. des = taskMain. element (XName. get ("Des ","")). value; config. userName = taskMain. element (XName. get ("UserName ","")). value; config. userPwd = taskMain. element (XName. get ("UserPwd ","")). value; config. apiKey = taskMain. element (XName. get ("ApiKey ","")). value; config. apiUrl = taskMain. element (XName. get ("ApiUrl ","")). value; config. closeTask = taskMain. element (XName. get ("CloseTask ","")). value = "1";} catch (Exception ex) {config. tpError = ex. message; PublicClass. _ WriteLog ($ "{config. name} Initialization Configuration Information exception: {ex. message} "," BaseLog "); throw new Exception (ex. message);} return config ;} # endregion # region initialization-start loading _ Load // <summary> // initialization-start /// </summary> public virtual void TPlugin_Load () {PublicClass. _ WriteLog ("test") ;}# endregion # region releases the public void Dispose () {GC. suppressFinalize (this); // you do not need to call the Finalize method of this object.} public virtual void Dispose (Action action) {action ();} # endregion} # region configuration file XmlConfig public class XmlConfig {public XmlConfig () {}/// <summary> // time of the customizer (minutes) /// </summary> public int Timer {get; set ;}/// <summary> /// run Name /// </summary> public string Name {get; set ;}//< summary> /// description (obtain the dll description for the first time and the description of the xml configuration file for the later part) /// </summary> public string Des {get; set ;}//< summary> /// interface account /// </summary> public string UserName {get; set ;} /// <summary> /// Interface Password /// </summary> public string UserPwd {get; set ;} /// <summary> /// interface key /// </summary> public string ApiKey {get; set ;} /// <summary> /// interface address // </summary> public string ApiUrl {get; set ;} /// <summary> /// whether to close the task /// </summary> public bool CloseTask {get; set ;} /// <summary> /// plug-in error // </summary> public string TpError {get; set ;} /// <summary> // xml Information // </summary> public XDocument doc {get; set ;}# endregion}

The specific description and logic processing code are annotated. You can take a look at it in detail. Here we want to tell you that the main principle of this framework is to dynamically load the task dll to create objects, the Assembly class Assembly of netcore does not have as many methods as the Assembly in the framework. I use Assembly here. load (), netcore can only Load the dll of the current system root directory (here I spent a few hours testing, friends with different results, please contact me in time Thank you), the framework uses the Task. run () method to create different tasks for parallel execution, and try... catch is used for fault tolerance. It avoids all the interruptions of the framework after a subtask exception. I personally think it is still good;

The following are several compressed packages in different environments for use and reference:

TaskCore. MainForm-pure file TaskCore. MainForm01 git Source Code address

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.