2016-04-05 9 views
0

を使用して、すべてのクラスの使用法を置き換えます は、我々はアセンブリOldAssembly内のクラスClass1を持っていると仮定しましょう。 このアセンブリは、多数の不明なプロジェクトによって参照されています。 このクラスを新しいアセンブリNewAssemblyに移動する予定です。最終的に名前と名前空間も変更されます。すべての用途を調整する必要があります。 これらのコード調整を自動化するツールを作成したいと思います。私がこれまでにやった私がやろうとしています何ロスリン

私はロスリンRenamerの周り果たしている:

var workspace = MSBuildWorkspace.Create(); 
var originalSln = workspace.OpenSolutionAsync(@"D:\spikes\ToBeFixed\ToBeFixed.sln").Result; 

var project = originalSln.Projects.Single(); 
var compilation = project.GetCompilationAsync().Result; 

var renameFrom = compilation.GetSymbolsWithName(s => s.Contains("Class1")).Single(); 
const string renameTo = "Class2"; 
var optionSet = originalSln.Workspace.Options; 
var modifiedSln = Renamer.RenameSymbolAsync(originalSln, renameFrom, renameTo, optionSet).Result; 

workspace.TryApplyChanges(modifiedSln); 

それはまた、ソースクラスの名前を変更します。だから私はRenamerコードを調べて、それを私のユースケースに適応させようとしましたが、そこで使われている内部構造のために失敗しました。

質問: クラスをあるアセンブリから別のアセンブリに移動した後で、コードの調整を自動化する方法を教えてください。

+0

あなたは最初にすべての名前を変更することができ、その後、その後、元のクラス名を修正しますか? – JoshVarty

+0

はい、しかし、 "名前を戻す"の範囲を1つのクラスに減らす方法はありません。クラス宣言でクラス名だけを変更するだけでは不十分です。 –

+0

クラスのすべての用途*を変更する必要がありますか?元のクラスを正確に元のままにしたいですか? – JoshVarty

答えて

2

次の方法で、あなたが探しているものを達成することができます全体のソリューションを元の自己と名前を変更したクラス自体を交換

  • 全体のクラスのすべての使用を名前変更

    1. public async static Task TestingRenamer() 
      { 
          var code = @" 
          using System; 
      
          //We do not want to rename MyClass (we want to keep it the same) 
          public class MyClass 
          { 
           public MyClass() 
           { 
           } 
          } 
      
          public class Program 
          { 
           public static void Main() 
           { 
            //We want to rename this usage 
            var x = new MyClass(); 
           } 
          }"; 
      
          var newClassName = "MY_NEW_CLASS_NAME"; 
          var document = getDocumentForCode(code); 
          var compilation = await document.Project.GetCompilationAsync(); 
      
          var root = await document.GetSyntaxRootAsync(); 
          var originalClass = root.DescendantNodesAndSelf().OfType<ClassDeclarationSyntax>().First(); 
      
          var model = compilation.GetSemanticModel(root.SyntaxTree); 
          var originalSymbol = model.GetDeclaredSymbol(originalClass); 
      
          //Rename all 
          var newSolution = await Renamer.RenameSymbolAsync(document.Project.Solution, originalSymbol, newClassName, document.Project.Solution.Workspace.Options); 
      
          //Revert the original class 
          var newDocument = newSolution.GetDocument(document.Id); 
          var newSyntaxRoot = await newDocument.GetSyntaxRootAsync(); 
          var newClass = newSyntaxRoot.DescendantNodes().OfType<ClassDeclarationSyntax>().Where(n => n.Identifier.ToString() == newClassName).Single(); 
          newSyntaxRoot = newSyntaxRoot.ReplaceNode(newClass, originalClass); 
          newDocument = newDocument.WithSyntaxRoot(newSyntaxRoot); 
      
          //We've now renamed all usages and reverted the class back to its original self. 
          var finalSolution = newDocument.Project.Solution; 
      } 
      
      //Helper method to build Document 
      private static Document getDocumentForCode(string code) 
      { 
          var ws = new AdhocWorkspace(); 
          var Mscorlib = MetadataReference.CreateFromAssembly(typeof(object).Assembly); 
          var references = new List<MetadataReference>() { Mscorlib }; 
          var projInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Default, "MyProject", "MyAssembly", "C#", metadataReferences: references); 
          var project = ws.AddProject(projInfo); 
      
          var text = SourceText.From(code); 
          var myDocument = ws.AddDocument(project.Id, "MyDocument.cs", text); 
          return myDocument; 
      } 
      
  • 関連する問題