예제 #1
0
        /// <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);
            }
        }