2017-01-16 54 views
2

我試圖讓自己的移動到資源重構(就像ReSharper中發現的那樣)。在我CodeAction.GetChangedDocumentAsync方法我在做這3個步驟:移動到資源重構

  1. 添加我的資源到Resources.resx文件,XmlDocument
  2. 使用DTE運行自定義工具來更新Resources.Designer.cs文件
  3. 由新資源的合格標識與SyntaxNode.ReplaceNode

步驟1 & 2都OK,但3不起作用替換文本字符串。如果我刪除步驟2,則3正在工作。

我不知道是不是因爲我在混合Roslyn & DTE,或者是因爲第2步在解決方案中生成新代碼並且我的緩存上下文變得無效。

// Add the resource to the Resources.resx file 
var xmlDoc = new XmlDocument(); 
xmlDoc.Load(resxPath); 
XmlNode node = xmlDoc.SelectSingleNode($"//data[@name='{resourceIndentifierName}']"); 
if (node != null) return; 
XmlElement dataElement = xmlDoc.CreateElement("data"); 

XmlAttribute nameAtt = xmlDoc.CreateAttribute("name"); 
nameAtt.Value = resourceIndentifierName; 
dataElement.Attributes.Append(nameAtt); 

XmlAttribute spaceAtt = xmlDoc.CreateAttribute("space", "xml"); 
spaceAtt.Value = "preserve"; 
dataElement.Attributes.Append(spaceAtt); 

XmlElement valueElement = xmlDoc.CreateElement("value"); 
valueElement.InnerText = value; 
dataElement.AppendChild(valueElement); 

XmlNode rootNode = xmlDoc.SelectSingleNode("//root"); 
Debug.Assert(rootNode != null, "rootNode != null"); 
rootNode.AppendChild(dataElement); 
xmlDoc.Save(resxPath); 

// Update the Resources.Designer.cs file 
var dte = (DTE2)Package.GetGlobalService(typeof(SDTE)); 
ProjectItem item = dte.Solution.FindProjectItem(resxPath); 
((VSProjectItem) item.Object)?.RunCustomTool(); 

// Replace the node 
SyntaxNode oldRoot = await context.Document.GetSyntaxRootAsync(cancellationToken) 
    .ConfigureAwait(false); 
SyntaxNode newRoot = oldRoot.ReplaceNode(oldNode, newNode); 
return context.Document.WithSyntaxRoot(newRoot); 
+0

什麼是'newNode'? – SLaks

+0

'newNode'是一個'QualifiedName':Properties.Resources.MyResource – Maxence

+0

究竟發生了什麼?但你不能這樣做;代碼操作必須是純函數。例如,懸停預覽怎麼樣? – SLaks

回答

2

這是因爲第2步中產生的新的解決方案的代碼和我的緩存方面變得無效

這是發生了什麼。當您致電RunCustomTool時,visual studio文件觀察器api會告訴roslyn文件已更新,roslyn會生成一組新的解決方案快照。當您嘗試應用您的代碼修補程序時,roslyn會查看您的代碼修補程序來自的解決方案快照,發現它與當前快照不匹配,並且無法應用它。

+0

我已經實現了'GetChangedSolutionAsync'而不是'GetChangedDocumentAsync',我正在用Roslyn更新.Designer.cs,而不是用'RunCustomTool'來完成。它完美的作品。非常感謝。 – Maxence

+0

最後它不起作用,因爲我的重構和** ResXFileCodeGenerator **之間存在衝突。每次修改.resx時,.Designer.cs都將由** ResXFileCodeGenerator **進行更新,並且我的快照將變爲無效。如果我禁用了** ResXFileCodeGenerator **,則.Designer.cs將從解決方案中消失。我將把它作爲一個標準的VS命令。 – Maxence