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

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

  • 相关阅读:
    JavaScript ECMAScript 2015 (ES6) 和 ECMAScript 2016 (ES7) 新特性速查
    Sass中文文档
    TypeScript手册中文版
    敏捷:什么是用户故事(User Story)
    Repeater为空时显示“暂无数据”,很方便实用方法
    jquery之css()改变字体大小,颜色,背景色
    七牛 在线管理 v0.1
    clion idea jetbrain windows下搞c/c++
    amazeui 搜索 动态
    命令行启动软件
  • 原文地址:https://www.cnblogs.com/kugar/p/10550818.html
Copyright © 2011-2022 走看看