/// <summary> /// Generates all required classes and documents and returns modified solution. /// With that modified solution it is required to call Workspace.ApplyChanges() /// </summary> /// <param name="solution"></param> /// <param name="dtoLocation"></param> /// <param name="metadata"></param> /// <returns>Modified solution containing changes to apply to workspace</returns> public static async Task <Solution> WriteDto(this Solution solution, SolutionLocation dtoLocation, EntityMetadata metadata, bool generateMapper, bool addContractAttrs, bool addDataAnnotations) { var project = solution.Projects .Where(p => p.Name.Contains(dtoLocation.Project)) .OrderBy(p => p.Name) // Due to .NET core project which have more complex project name, cannot use == .FirstOrDefault(); var compilation = await project.GetCompilationAsync(); var existingDtoDocument = compilation.GetDocumentForSymbol(project.Solution, metadata.DtoName); SyntaxTree existingSyntaxTree = null; if (existingDtoDocument != null) { existingSyntaxTree = await existingDtoDocument.GetSyntaxTreeAsync(); } var dtoNamespace = dtoLocation.ToNamespace(project.AssemblyName); var mapperNamespace = "unknown"; var mapperDoc = compilation.GetDocumentForSymbol(project.Solution, "MapperBase"); if (mapperDoc == null && generateMapper) { var mapperFolderStructure = dtoLocation.GetFolders().Concat(new[] { "Infrastructure" }); mapperNamespace = dtoNamespace + ".Infrastructure"; project = project.AddDocument("MapperBase.cs", DtoBuilder.BuildMapper(mapperNamespace), folders: mapperFolderStructure).Project; } else if (generateMapper) { var mapperSyntax = await mapperDoc.GetSyntaxRootAsync(); mapperNamespace = mapperSyntax.DescendantNodesAndSelf(p => !p.IsKind(CSharp.SyntaxKind.NamespaceDeclaration)) .OfType <NamespaceDeclarationSyntax>() .Select(p => p.Name.ToString()) .FirstOrDefault(); } var syntaxTree = DtoBuilder.BuildDto(metadata, dtoNamespace: dtoNamespace, existingDto: existingSyntaxTree, mapperNamespace: mapperNamespace, generateMapper: generateMapper, addContractAttrs: addContractAttrs, addDataAnnotations: addDataAnnotations); if (existingDtoDocument == null) { var formatted = Formatter.Format(syntaxTree.GetRoot(), solution.Workspace); var folderStructure = dtoLocation.GetFolders(); var newDoc = project.AddDocument(metadata.DtoName + ".cs", formatted, folders: folderStructure); return(newDoc.Project.Solution); } else { var root = syntaxTree.GetRoot(); root = Formatter.Format(root, solution.Workspace); var newDoc = existingDtoDocument.WithSyntaxRoot(root); return(newDoc.Project.Solution); } }