2012-11-14 13 views
7

Desidero aggiungere una funzione (un TestMethod) a un file C# esistente. Dopo aver cercato su Google ho trovato la libreria EnvDTE e CodeModel.AddFunction -Method, ma non riesco a trovare un buon esempio di ciò che voglio.Aggiunta di funzioni al file C# esistente con EnvDTE

Vorrei aggiungere una funzione con codice già in quella funzione appena creata e anche con un attributo. Qualcosa del genere:

/// <summary> 
/// Documentation 
/// </summary> 
[TestMethod] 
public void TestMethod1() 
{ 
    string test = Helper.CodeExample(); 
} 

Qualcuno può mostrarmi un esempio su come farlo?

EDIT: Voglio modificare un file C#, come se si modificasse un file di testo. So che potresti farlo con uno StreamWriter, ma c'è forse un modo migliore per farlo?

+0

cosa si intende la modifica di un file C# (testo) o C# (NET) classe? La modifica del testo è completamente diversa dalla modifica del codice compilato. – larsmoa

+0

Intendo un file di testo C#. È per generare file di test. Posso farlo con uno StreamWriter, ma penso che forse c'è un modo migliore per farlo. – Mathieu

+0

È necessario trovare qualcosa che possa analizzare il codice in un albero di sintassi, quindi adattare l'albero di sintassi per aggiungere la propria funzione e quindi generare un nuovo file da tale albero di sintassi. –

risposta

5

EnvDTE può essere la strada da percorrere. È possibile sviluppare un componente aggiuntivo VisualStudio e quindi modificare il metodo Exec. In questo metodo devi ottenere il documento attivo e il suo oggetto ProjectItem. Questo è dove si trova il CodeModel che contiene molti CodeElements. Tra questi elementi devi trovare lo spazio CodeNames e all'interno di questo elemento CodeClass. Questo è l'oggetto che risponde ad AddFunction restituendo il nuovo CodeFunction al quale è possibile aggiungere il proprio attributo e il codice (questa è una parte che non mi piace troppo, dal momento che è necessario utilizzare EditPoint).

Questa è una versione molto semplice di Exec che è possibile utilizzare come punto di partenza:

public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled) 
    { 
     handled = false; 
     if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault) 
     { 
      handled = true; 
      if (commandName == "TestAddMethod.Connect.TestAddMethod") 
      { 
       Document activeDoc = _applicationObject.ActiveDocument; 
       if (activeDoc == null) 
        return; 
       ProjectItem prjItem = activeDoc.ProjectItem; 
       if (prjItem == null) 
        return; 
       FileCodeModel fcm = prjItem.FileCodeModel; 
       if (fcm == null) 
        return; 

       CodeElements ces = fcm.CodeElements; 
       // look for the namespace in the active document 
       CodeNamespace cns = null; 
       foreach (CodeElement ce in ces) 
       { 
        if (ce.Kind == vsCMElement.vsCMElementNamespace) 
        { 
         cns = ce as CodeNamespace; 
         break; 
        } 
       } 
       if (cns == null) 
        return; 
       ces = cns.Members; 
       if (ces == null) 
        return; 
       // look for the first class 
       CodeClass cls = null; 
       foreach (CodeElement ce in ces) 
       { 
        if (ce.Kind == vsCMElement.vsCMElementClass) 
        { 
         cls = ce as CodeClass; 
         break; 
        } 
       } 
       if (cls == null) 
        return; 
       CodeFunction cf = cls.AddFunction("TestMethod1", vsCMFunction.vsCMFunctionFunction, vsCMTypeRef.vsCMTypeRefVoid, -1, vsCMAccess.vsCMAccessPrivate); 
       cf.AddAttribute("TestMethod", "true"); 
       TextPoint tp = cf.GetStartPoint(vsCMPart.vsCMPartBody); 
       EditPoint ep = tp.CreateEditPoint(); 
       ep.Indent(); 
       ep.Indent(); 
       ep.Indent(); 
       ep.Insert("string test = Helper.CodeExample();"); 
      } 
     } 
    } 
+0

Questo è quello che sto cercando! Questo è molto meglio che semplicemente modificare il file CS come un file di testo. Molte grazie! – Mathieu

+1

Questo è stato un fantastico punto di partenza per me! Grazie! Vale anche la pena notare che è possibile eseguire 'SmartFormat' piuttosto che i trattini. È in grado di formattare un intervallo di codice a partire dal chiamante 'EditPoint' e terminare con il parametro' TextPoint'. Ecco un esempio utilizzando il codice precedente: 'ep.Insert (" string test = Helper.CodeExample(); ");' 'tp.CreateEditPoint(). SmartFormat (ep);' – philt5252

Problemi correlati