zoukankan      html  css  js  c++  java
  • 与下位机或设备的通信解析优化的一点功能(续补):动态编译

        继上一篇《与下位机或设备的通信解析优化的一点功能: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("	{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

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

  • 相关阅读:
    克如斯卡尔 P1546
    真正的spfa
    第四课 最小生成树 要点
    关于vscode中nullptr未定义
    cmake学习笔记
    python学习笔记
    (BFS 图的遍历) 2906. kotori和迷宫
    (图论基础题) leetcode 997. Find the Town Judge
    (BFS DFS 并查集) leetcode 547. Friend Circles
    (BFS DFS 图的遍历) leetcode 841. Keys and Rooms
  • 原文地址:https://www.cnblogs.com/kugar/p/10550818.html
Copyright © 2011-2022 走看看