我正在研究在使用VisualStudioWorkspace更新现有代码的Visual Studio扩展(VSIX)中使用Roslyn编译器。花了几天的时间阅读这篇文章,似乎有几种方法可以实现这一目标......我只是不确定哪种方法适合我。Roslyn将新方法添加到现有类
好了,让我们假设用户有他们的解决方案在Visual Studio 2015年开放,他们点击我的推广和(通过一种形式),他们告诉我,他们希望下面的方法定义添加到一个接口:
GetSomeDataResponse GetSomeData(GetSomeDataRequest request);
他们还告诉我接口的名称,它是ITheInterface。
界面中已经有一些代码:
namespace TheProjectName.Interfaces
{
using System;
public interface ITheInterface
{
/// <summary>
/// A lonely method.
/// </summary>
LonelyMethodResponse LonelyMethod(LonelyMethodRequest request);
}
}
好了,这样我就可以使用加载接口文档如下:
Document myInterface = this.Workspace.CurrentSolution?.Projects?
.FirstOrDefault(p
=> p.Name.Equals("TheProjectName"))
?.Documents?
.FirstOrDefault(d
=> d.Name.Equals("ITheInterface.cs"));
那么,什么是现在添加的最佳方式我的新方法到这个现有的接口,最好是在XML评论(三斜杠评论)写?请记住请求和响应类型(GetSomeDataRequest和GetSomeDataResponse)可能实际上还不存在。我对此很新,所以如果你可以提供代码示例,那就太棒了。
UPDATE
我决定(可能)最好的办法是简单地在一些文字注入,而不是试图以编程方式建立的方法声明。
我尝试以下,但结束了一个例外,我不理解:
SourceText sourceText = await myInterface.GetTextAsync();
string text = sourceText.ToString();
var sb = new StringBuilder();
// I want to all the text up to and including the last
// method, but without the closing "}" for the interface and the namespace
sb.Append(text.Substring(0, text.LastIndexOf("}", text.LastIndexOf("}") - 1)));
// Now add my method and close the interface and namespace.
sb.AppendLine("GetSomeDataResponse GetSomeData(GetSomeDataRequest request);");
sb.AppendLine("}");
sb.AppendLine("}");
检查这一点,这一切都很好(我真正的代码添加格式和XML注释,但去除,为了清楚)。
因此,知道这些是不可变的,我试图挽救它,如下所示:
var updatedSourceText = SourceText.From(sb.ToString());
var newInterfaceDocument = myInterface.WithText(updatedSourceText);
var newProject = newInterfaceDocument.Project;
var newSolution = newProject.Solution;
this.Workspace.TryApplyChanges(newSolution);
但是,这创造了以下异常:
bufferAdapter is not a VsTextDocData
在Microsoft.VisualStudio.Editor。 Implementation.VsEditorAdaptersFactoryService.GetAdapter(IVsTextBuffer bufferAdapter) at Microsoft.VisualStudio.Editor.Implementation.VsEditorAdaptersFactoryService.GetDocumentBuffer(IVsTextBuffer bufferAdapter) 在Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.InvisibleEditor..ctor(的IServiceProvider的ServiceProvider,字符串文件路径,布尔needsSave,布尔needsUndoDisabled) 在Microsoft.VisualStudio.LanguageServices.RoslynVisualStudioWorkspace.OpenInvisibleEditor(IVisualStudioHostDocument hostDocument) 在Microsoft.VisualStudio。 LanguageServices.Implementation.ProjectSystem.DocumentProvider.StandardTextDocument.UpdateText(SourceText newText) 在Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.VisualStudioWorkspaceImpl.ApplyDocumentTextChanged(documentId documentId,SourceText newText) 在Microsoft.CodeAnalysis.Workspace。ApplyProjectChanges(ProjectChanges projectChanges) 在Microsoft.CodeAnalysis.Workspace.TryApplyChanges(解决方案newSolution) 在Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.VisualStudioWorkspaceImpl.TryApplyChanges(解决方案newSolution)
您可能需要通过调用'SourceText.WithChanges(new TextChange(...))'来更改现有的'SourceText'(它附加了附加的源文件信息),[请参阅本答案](http: //stackoverflow.com/a/37553697/155005)为例。 – m0sa