/// <summary> /// Create Assembly whick will run /// </summary> /// <param name="script"></param> /// <param name="errorMsg"></param> /// <returns></returns> private Assembly CreateAsmExecutor(string script, out string errorMsg) { errorMsg = null; var assemblyName = _scriptHash; var references = CSharpReferenceManager.GetMetaDataReferences()[_currentAppName]; var compilation = CSharpCompilation.Create(assemblyName, new[] { GetSyntaxTree(script) }, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithOptimizationLevel(FaaSSettingsConfigHelper.IsDebugMode() ? OptimizationLevel.Debug : OptimizationLevel.Release)); Assembly assembly = null; using (var assemblyStream = new MemoryStream()) { using (var pdbStream = new MemoryStream()) { var emitDynamicScriptExecuteResult = compilation.Emit(assemblyStream, pdbStream); if (emitDynamicScriptExecuteResult.Success) { var assemblyBytes = assemblyStream.GetBuffer(); var pdbBytes = pdbStream.GetBuffer(); assembly = Assembly.Load(assemblyBytes, pdbBytes); //output files if (FaaSSettingsConfigHelper.IsOutPutFiles()) { OutputDynamicScriptAllFile(script, assemblyName, assemblyBytes, pdbBytes); } } else { var msgs = new StringBuilder(); foreach (var msg in emitDynamicScriptExecuteResult.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error).Select(d => string.Format("[{0}]:{1}({2})", d.Id, d.GetMessage(), d.Location.GetLineSpan().StartLinePosition))) { msgs.AppendLine(msg); } if (FaaSSettingsConfigHelper.IsOutPutFiles()) { WriteDynamicScriptCs(Path.Combine(EnsureOutputPath(), assemblyName + ".cs"), script); } errorMsg = msgs.ToString(); _logger.LogError(String.Format("{0}:{1}:{2}:{3}:{4}", _tenantId, "CSharp", _currentAppName, errorMsg, _scriptHash)); } } } _logger.LogInformation($"CreateAsmExecutor -> _context:{_tenantId},{"CSharp"}, {_currentAppName},{_scriptHash} _scriptTypeDict:{_scriptTypeDict?.Count} _metadataReferences:{ CSharpReferenceManager.GetMetaDataReferences()[_currentAppName]?.Count}"); return(assembly); }
/// <summary> /// 引用第三方包,配置文件中配置引用key=对应服务的应用名 /// </summary> private static void ReferenceAssembly() { //这里配置的程序集引用要写文件全名,包括路径和后缀 var assemblyInfos = AssemblyReferenceConfig.GetCurrentAppAssemblyReferenceInfos(); //为不为空都把默认执行路径加上扫描 var dirs = FaaSSettingsConfigHelper.GetReferenceDirs(); if (dirs == null) { dirs = new List <string>(); } dirs.Insert(0, AppContext.BaseDirectory); dirs.Add(Path.GetDirectoryName(typeof(object).Assembly.Location)); _logger.LogInformation($"scan config dirs: [{string.Join(",", dirs)}]."); if (assemblyInfos == null || !assemblyInfos.Any()) { return; } foreach (var assemblyInfo in assemblyInfos) { foreach (var dir in dirs) { var fileFullPath = Path.Combine(dir, assemblyInfo.Assembly); if (!File.Exists(fileFullPath)) { continue; } //如果文件存在,则加载完成后跳过后续扫描 _metadataReferences[_currentAppName].Add(MetadataReference.CreateFromFile(fileFullPath)); break; } } }
public void GetReferenceDirs() { var referenceDirs = FaaSSettingsConfigHelper.GetReferenceDirs(); Assert.NotEmpty(referenceDirs); }