/// <summary>Generates the Swagger definition for the given classes without operations (used for class generation).</summary> /// <param name="classNames">The class names.</param> /// <returns>The Swagger definition.</returns> public override SwaggerDocument Generate(string[] classNames) { var loader = new NetAssemblyLoader(); var data = loader.FromAssemblyType(classNames, JsonConvert.SerializeObject(Settings)); return(SwaggerDocument.FromJson(data)); }
/// <summary> /// Find all using directive<br/> /// And try to load the namespace as assembly<br/> /// 寻找源代码中的所有using指令<br/> /// 并尝试加载命名空间对应的程序集<br/> /// </summary> /// <param name="syntaxTrees">Syntax trees</param> protected void LoadAssembliesFromUsings(List <SyntaxTree> syntaxTrees) { // Find all using directive var assemblyLoader = new NetAssemblyLoader(); foreach (var tree in syntaxTrees) { foreach (var usingSyntax in ((CompilationUnitSyntax)tree.GetRoot()).Usings) { var name = usingSyntax.Name; var names = new List <string>(); while (name != null) { // The type is "IdentifierNameSyntax" if it's single identifier // eg: System // The type is "QualifiedNameSyntax" if it's contains more than one identifier // eg: System.Threading if (name is QualifiedNameSyntax qualifiedName) { var identifierName = (IdentifierNameSyntax)qualifiedName.Right; names.Add(identifierName.Identifier.Text); name = qualifiedName.Left; } else if (name is IdentifierNameSyntax identifierName) { names.Add(identifierName.Identifier.Text); name = null; } } if (names.Contains("src")) { // Ignore if it looks like a namespace from plugin continue; } names.Reverse(); for (int c = 1; c <= names.Count; ++c) { // Try to load the namespace as assembly // eg: will try "System" and "System.Threading" from "System.Threading" var usingName = string.Join(".", names.Take(c)); if (LoadedNamespaces.Contains(usingName)) { continue; } try { assemblyLoader.Load(usingName); } catch { // Retry next name } LoadedNamespaces.Add(usingName); } } } }
/// <summary>Generates the Swagger definition for the given classes without operations (used for class generation).</summary> /// <param name="classNames">The class names.</param> /// <returns>The Swagger definition.</returns> public override SwaggerDocument Generate(string[] classNames) { #if FullNet using (var isolated = new AppDomainIsolation <NetAssemblyLoader>(Path.GetDirectoryName(Path.GetFullPath(Settings.AssemblyPath)), Settings.AssemblyConfig)) return(SwaggerDocument.FromJson(isolated.Object.FromAssemblyType(classNames, JsonConvert.SerializeObject(Settings)))); #else var loader = new NetAssemblyLoader(); var data = loader.FromAssemblyType(classNames, JsonConvert.SerializeObject(Settings)); return(SwaggerDocument.FromJson(data)); #endif }
/// <summary>Generates the Swagger definition for the given classes without operations (used for class generation).</summary> /// <param name="classNames">The class names.</param> /// <returns>The Swagger definition.</returns> public override SwaggerDocument Generate(string[] classNames) { #if FullNet using (var isolated = new AppDomainIsolation<NetAssemblyLoader>(Path.GetDirectoryName(Path.GetFullPath(Settings.AssemblyPath)), Settings.AssemblyConfig)) return SwaggerDocument.FromJson(isolated.Object.FromAssemblyType(classNames, JsonConvert.SerializeObject(Settings))); #else var loader = new NetAssemblyLoader(); var data = loader.FromAssemblyType(classNames, JsonConvert.SerializeObject(Settings)); return SwaggerDocument.FromJson(data); #endif }
/// <summary>Generates the Swagger definition for the given classes without operations (used for class generation).</summary> /// <param name="classNames">The class names.</param> /// <returns>The Swagger definition.</returns> public override async Task <SwaggerDocument> GenerateAsync(string[] classNames) { #if FullNet using (var isolated = new AppDomainIsolation <NetAssemblyLoader>(Path.GetDirectoryName(Path.GetFullPath(Settings.AssemblyPath)), Settings.AssemblyConfig)) { var json = await Task.Run(() => isolated.Object.FromAssemblyType(classNames, JsonConvert.SerializeObject(Settings))).ConfigureAwait(false); return(await SwaggerDocument.FromJsonAsync(json).ConfigureAwait(false)); } #else var loader = new NetAssemblyLoader(); var data = loader.FromAssemblyType(classNames, JsonConvert.SerializeObject(Settings)); return(await SwaggerDocument.FromJsonAsync(data).ConfigureAwait(false)); #endif }
/// <summary>Gets the available controller classes from the given assembly.</summary> /// <returns>The controller classes.</returns> public override string[] GetClasses() { if (File.Exists(Settings.AssemblyPath)) { #if FullNet using (var isolated = new AppDomainIsolation<NetAssemblyLoader>(Path.GetDirectoryName(Path.GetFullPath(Settings.AssemblyPath)), Settings.AssemblyConfig)) return isolated.Object.GetClasses(Settings.AssemblyPath, GetAllReferencePaths(Settings)); #else var loader = new NetAssemblyLoader(); return loader.GetClasses(Settings.AssemblyPath, GetAllReferencePaths(Settings)); #endif } else return new string[] { }; }
/// <summary>Gets the available controller classes from the given assembly.</summary> /// <returns>The controller classes.</returns> public override string[] GetClasses() { if (File.Exists(Settings.AssemblyPath)) { #if FullNet using (var isolated = new AppDomainIsolation <NetAssemblyLoader>(Path.GetDirectoryName(Path.GetFullPath(Settings.AssemblyPath)), Settings.AssemblyConfig)) return(isolated.Object.GetClasses(Settings.AssemblyPath, GetAllReferencePaths(Settings))); #else var loader = new NetAssemblyLoader(); return(loader.GetClasses(Settings.AssemblyPath, GetAllReferencePaths(Settings))); #endif } else { return new string[] { } }; }
/// <summary> /// Compile source files to assembly<br/> /// 编译源代码到程序集<br/> /// </summary> public void Compile(IList <string> sourceFiles, string assemblyName, string assemblyPath) { // Parse source files into syntax trees // Also define NETCORE for .Net Core var parseOptions = CSharpParseOptions.Default; parseOptions = parseOptions.WithPreprocessorSymbols("NETCORE"); var syntaxTrees = sourceFiles .Select(path => CSharpSyntaxTree.ParseText( File.ReadAllText(path), parseOptions, path, Encoding.UTF8)) .ToList(); LoadAssembliesFromUsings(syntaxTrees); // Add loaded assemblies to compile references var assemblyLoader = new NetAssemblyLoader(); var references = assemblyLoader.GetLoadedAssemblies() .Select(assembly => assembly.Location) .Select(path => MetadataReference.CreateFromFile(path)) .ToList(); var optimizationLevel = OptimizationLevel.Release; var compilationOptions = new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary, optimizationLevel: optimizationLevel); // Compile to assembly, throw exception if error occurred Microsoft.CodeAnalysis.CSharp.CSharpCompilation compilation = CSharpCompilation.Create(assemblyName) .WithOptions(compilationOptions) .AddReferences(references) .AddSyntaxTrees(syntaxTrees); Microsoft.CodeAnalysis.Emit.EmitResult emitResult = compilation.Emit(assemblyPath); if (!emitResult.Success) { throw new Exception(string.Join("\r\n", emitResult.Diagnostics.Where(d => d.WarningLevel == 0))); } }