I want to programmatically add a function (a TestMethod) to an existing C#-file.
After some googling I have found the library EnvDTE
and CodeModel.AddFunction
-Method, but I can't find a good example of what I want.
I would like to add a function with code already in that newly created function and also with an attribute. Something like this:
/// <summary>
/// Documentation
/// </summary>
[TestMethod]
public void TestMethod1()
{
string test = Helper.CodeExample();
}
Can anyone show me an example on how to do this?
EDIT: I want to edit a C# file, like you would edit a text-file. I know you could do this with a StreamWriter, but is there maybe a better way for doing this?
EnvDTE can be the way to go. You can develop a VisualStudio Add-In and then modify the Exec method. In this method you have to get the active document and its ProjectItem. This is where you find the CodeModel which contains a lot of CodeElements. Among these elements you have to find the CodeNamespace, and inside this element the CodeClass. This is the object that responds to AddFunction returning the new CodeFunction to which you can add your attribute and the code (this is a part I don't like too much, since you have to use EditPoint).
This is a very simple version of Exec that you can use as a starting point:
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();");
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With