原文:与下位机或设备的通信解析优化的一点功能(续补):动态编译
继上一篇《与下位机或设备的通信解析优化的一点功能: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); //实例化解析类
.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 }
两种框架下的生成稍微有点不同,列出来,,复制粘贴一下,,改一改就可以用上去了
来源:https://www.cnblogs.com/lonelyxmas/p/12345287.html

