与下位机或设备的通信解析优化的一点功能(续补):动态编译

时间:2019-03-19
本文章向大家介绍与下位机或设备的通信解析优化的一点功能(续补):动态编译,主要包括与下位机或设备的通信解析优化的一点功能(续补):动态编译使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

    继上一篇《与下位机或设备的通信解析优化的一点功能:T4+动态编译》  ,现在已经生成出解析用的类的C#源码了,接下来,就轮到动态编译生成Type了。

    在实现上,。net framework和。net core上,有些不同:

    .Net Framework的:

 1  var transfer = "";  //解析后的C#源码字符串
 2 
 3                 ICodeCompiler comp = new CSharpCodeProvider().CreateCompiler();
 4 
 5                 //编译器的传入参数   
 6                 CompilerParameters cp = new CompilerParameters();
 7 
 8                 //引入对应的dll
 9                 cp.ReferencedAssemblies.Add("system.dll"); //添加程序集 system.dll 的引用   
10                 cp.ReferencedAssemblies.Add("system.data.dll"); //添加程序集 system.data.dll 的引用   
11                 cp.ReferencedAssemblies.Add("system.xml.dll"); //添加程序集 system.xml.dll 的引用
12                 cp.ReferencedAssemblies.Add("Kugar.Core.dll");
13                 cp.ReferencedAssemblies.Add("Newtonsoft.Json.dll");
14                 cp.ReferencedAssemblies.Add("Kugar.GPS.Api.Data.dll");
15                 cp.ReferencedAssemblies.Add("Kugar.GPS.Api.BLL.dll");
16                 cp.ReferencedAssemblies.Add("MongoDB.Bson.dll");
17                 cp.ReferencedAssemblies.Add("MongoDB.Driver.Core.dll");
18 
19                 cp.GenerateExecutable = false; //不生成可执行文件   
20                 cp.GenerateInMemory = true; //在内存中运行   
21                 cp.IncludeDebugInformation = false;
22 
23                 CompilerResults results = comp.CompileAssemblyFromSource(cp, transfer);
24 
25                 if (results.Errors.HasErrors)
26                 {
27                     foreach (CompilerError error in results.Errors)
28                     {
29                         LoggerManager.Default.Debug("生成类出错:" + error.ErrorText);
30                     }
31 
32                     return null;
33                 }
34                 
35                 //获取生成后的应用程序集中,对应的类Type
36                 var type = results.CompiledAssembly.GetTypes()
37                     .Where(x => x.IsImplementlInterface(typeof(IProtocolExecutor))).FirstOrDefault();
38 
39                 return (IProtocolExecutor) Activator.CreateInstance(type, newProtocol.ProtocolID,newProtocol.Version);  //实例化解析类
View Code

   .Net Core 下的:

    Nuget下安装 System.Runtime.Loader,System.CodeDom,Microsoft.CodeAnalysis.CSharp包

 1 var transfer = ""; //T4生成出来的C#源码
 2 
 3                 SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(transfer);
 4 
 5 
 6                 string assemblyName = Path.GetRandomFileName();
 7                 MetadataReference[] references = null;
 8 
 9                 try
10                 {
11                     //添加当前应用程序域里所有的dll引用
12                     references = DependencyContext.Default
13                         .CompileLibraries
14                         .SelectMany(x => x.ResolveReferencePaths(new ReferenceAssemblyPathResolver()))
15                         .Where(path => !string.IsNullOrWhiteSpace(path))
16                         .Select(path => MetadataReference.CreateFromFile(path)).ToArrayEx();
17 
18                    
19                 }
20                 catch (Exception e)
21                 {
22                     Console.WriteLine(e);
23                     throw;
24                 }
25 
26                 CSharpCompilation compilation = CSharpCompilation.Create(
27                     assemblyName,
28                     syntaxTrees: new[] { syntaxTree },
29                     references: references,
30                     options:new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
31                     );
32 
33                 using (var ms = new MemoryStream())
34                 {
35                     EmitResult result = compilation.Emit(ms);
36 
37                     if (!result.Success)
38                     {
39                         IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
40                             diagnostic.IsWarningAsError ||
41                             diagnostic.Severity == DiagnosticSeverity.Error);
42 
43                         foreach (Diagnostic diagnostic in failures)
44                         {
45                             Console.Error.WriteLine("\t{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
46                         }
47 
48                         return null;
49                     }
50                     else
51                     {
52                         ms.Seek(0, SeekOrigin.Begin);
53 
54                         Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
55 
56                         var type = assembly.GetTypes()
57                             .Where(x => x.IsImplementlInterface(typeof(IProtocolExecutor))).FirstOrDefault();
58 
59                         return (IProtocolExecutor)Activator.CreateInstance(type, newProtocol.ProtocolID, newProtocol.Version);  //实例化解析类
60 
61                     }
62                 }
View Code

   两种框架下的生成稍微有点不同,列出来,,复制粘贴一下,,改一改就可以用上去了