2012-11-14 15 views
7

Chcę programowo dodać funkcję (TestMethod) do istniejącego pliku C#. Po pewnym przeszukaniu go znalazłem bibliotekę EnvDTE i CodeModel.AddFunction -Method, ale nie mogę znaleźć dobrego przykładu tego, czego chcę.Programowo dodaj funkcję do istniejącego pliku C# za pomocą EnvDTE

Chciałbym dodać funkcję z kodem już w tej nowo utworzonej funkcji, a także z atrybutem. Coś takiego:

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

Czy ktoś może pokazać mi przykład, jak to zrobić?

EDYCJA: Chcę edytować plik C#, tak jak w przypadku edycji pliku tekstowego. Wiem, że możesz to zrobić za pomocą StreamWriter, ale czy jest lepszy sposób na zrobienie tego?

+0

masz na myśli modyfikując plik C# (tekst) lub C# (.NET) klasę? Modyfikowanie tekstu jest zupełnie inne niż modyfikowanie skompilowanego kodu. – larsmoa

+0

Mam na myśli plik tekstowy C#. Służy do generowania plików testowych. Mogę to zrobić za pomocą StreamWriter, ale może istnieje lepszy sposób na zrobienie tego. – Mathieu

+0

Musisz znaleźć coś, co może parsować kod w drzewie składni, a następnie dostosować drzewo składniowe, aby dodać swoją funkcję, a następnie wygenerować nowy plik z tego drzewa składni. –

Odpowiedz

5

EnvDTE może być najlepszym rozwiązaniem. Możesz rozwinąć dodatek VisualStudio, a następnie zmodyfikować metodę Exec. W tej metodzie musisz uzyskać aktywny dokument i jego ProjectItem. Tutaj znajdziesz CodeModel, który zawiera dużo CodeElements. Wśród tych elementów musisz znaleźć CodeNamespace, a wewnątrz tego elementu CodeClass. Jest to obiekt, który odpowiada na AddFunction zwracający nową funkcję CodeFunction, do której możesz dodać swój atrybut i kod (jest to część, której nie lubię zbyt wiele, ponieważ musisz używać EditPoint).

Jest to bardzo prosta wersja Exec, które można wykorzystać jako punkt wyjścia:

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

Tego właśnie szukam! Jest to o wiele lepsze niż edycja pliku cs, takiego jak plik tekstowy. Wielkie dzięki! – Mathieu

+1

To był fantastyczny punkt wyjścia dla mnie! Dziękuję Ci! Warto również zauważyć, że jest w stanie zrobić 'SmartFormat' zamiast wcięć. To smart formatuje zakres kodu zaczynając od wywołania 'EditPoint' i kończąc na parametrze' TextPoint'. Oto przykład użycia powyższego kodu: 'ep.Insert (" string test = Helper.CodeExample(); ");' 'tp.CreateEditPoint(). SmartFormat (ep);' – philt5252

Powiązane problemy