Прилагане на множество промени към решение в roslyn

Искам да приложа промени в няколко документа на решение, но само първата промяна се отразява, а останалите се отхвърлят.Тази връзка показва как само веднъж могат да бъдат приложени промени към решение. Какво би било заобикаляне на това. Ще се радвам на връзка, насочваща към решение или кодов фрагмент.

Ето моята функция:

public static async Task<bool> AddMethod(string solutionPath)
{
    var workspace = MSBuildWorkspace.Create(); 
    var solution = await workspace.OpenSolutionAsync(solutionPath);
    ClassDeclarationSyntax cls = SyntaxFactory.ClassDeclaration("someclass");

    foreach (var project in solution.Projects)
    {
        foreach(var document in project.Documents)
        {
            Document doc = project.GetDocument(document.Id);
            var root = await doc.GetSyntaxRootAsync();
            var classes = root.DescendantNodes().Where(n => n.IsKind(SyntaxKind.ClassDeclaration));
            if (classes.Count() != 0)
            {
                SyntaxNode FirstClass = classes.First() as ClassDeclarationSyntax;
                if (FirstClass != null)
                {
                    var newRoot = root.ReplaceNode(FirstClass, cls);
                    doc = doc.WithText(newRoot.GetText());
                    Project proj = doc.Project;
                    var abc = workspace.TryApplyChanges(proj.Solution);
                }
            }
        }
    }
    return true;
}

person Harjatin    schedule 17.07.2015    source източник
comment
Прилагате промени в старата версия на решението. Не можеш да направиш това.   -  person SLaks    schedule 17.07.2015
comment
@SLaks Разбрах тази част. Но каква е работата?   -  person Harjatin    schedule 17.07.2015


Отговори (1)


Заобиколното решение е да използвате ProjectId и DocumentId и да приложите всичките си промени в работното пространство наведнъж.

Опитайте следното:

public static async Task<bool> AddMethod(string solutionPath)
{
    var workspace = MSBuildWorkspace.Create();
    var solution = await workspace.OpenSolutionAsync(solutionPath);
    ClassDeclarationSyntax cls = SyntaxFactory.ClassDeclaration("someclass");

    foreach (var projectId in solution.ProjectIds)
    {
        var project = solution.GetProject(projectId);
        foreach (var documentId in project.DocumentIds)
        {
            Document doc = project.GetDocument(documentId);
            var root = await doc.GetSyntaxRootAsync();
            var firstClass = root.DescendantNodes().OfType<ClassDeclarationSyntax>().FirstOrDefault();
            if (firstClass == null)
                return true;

            var newRoot = root.ReplaceNode(firstClass, cls);
            doc = doc.WithText(newRoot.GetText());
            //Persist your changes to the current project
            project = doc.Project;
        }

        //Persist the project changes to the current solution
        solution = project.Solution;
    }
    //Finally, apply all your changes to the workspace at once.
    var abc = workspace.TryApplyChanges(solution);
    return true;
}
person JoshVarty    schedule 17.07.2015
comment
По мое мнение - това не е заобиколно решение, а планираният начин за манипулиране на решения в света на Рослин. Ако случаят е такъв - предлагам да редактирате отговора и да премахнете Заобиколното решение. - person Pavel Donchev; 14.05.2018
comment
Обърнете внимание, че ако разработвате разширение на Visual Studio, което трансформира множество документи, TryApplyChanges може да се провали поради проблем github.com/dotnet/roslyn/issues/25425 - person SARI; 18.06.2019