Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programatically insert a property to a class in .cs source file?

I am creating an automation tool for inserting properties to existing class's source code. E.g. I have an existing source code like this:

public class MyClass 
{
   //class members goes here

}

I want to modify it to become like this

public class MyClass 
{
   //class members goes here

   public string MyProp { get; set; }
}

and save it to the same file.

The class name, property type and property name will be known before hand and can be considered parameters of the operation. Any idea how to do this easily? Perhaps regex replace will work for this, but I don't know which expression to use that will be flexible regardless of the source code's new line, whitespace and identation policy.

EDIT: What I'm looking for is simply automatically generating the source code, not manipulating classes during runtime

like image 597
Louis Rhys Avatar asked Mar 18 '13 05:03

Louis Rhys


3 Answers

A clean way of doing this, is by using T4 templates to generate partial classes.

T4 templates are a good way to generate code at compile time.

These generated files should not be modified by the developer, instead the developer creates another file with additional definitions of members of the partial class.

That way you can tweak and run the generator again and again without messing with the custom code.

like image 145
Emond Avatar answered Nov 15 '22 02:11

Emond


The following approach using regular expressions should work, although I don't think this could be the best way of doing what you need. Don't really know, that depends on your needs. I do it all the time (either creating scripts that modify the .cs files, or macros from Notepad++). Perhaps you might also want to take a look at partial classes.

string text = 
@"namespace X {
    public class MyClass {
        //Text here
    }
}";
string className = "MyClass";
string propertyType = "string";
string propertyName = "MyProperty";

string regex = string.Format(@"( *)((public?)\s*(static)?\s*class\s+{0}\s*{{)", className);
string replacement = string.Format("$1$2\r\n\r\n$1    public {0} {1} {{ get; set; }}", propertyType, propertyName);

var modified = Regex.Replace(text, regex, replacement);
Console.WriteLine(modified);

The above code will print:

namespace X {
    public class MyClass {

        public string MyProperty { get; set; }
        //Text here
    }
}

Edit: As you can see, it indents the code correctly. It uses the same number of spaces of the line that contains the class definition + 4 more. If you want to add a tab, or whatever, you can change the regex.

like image 3
Oscar Mederos Avatar answered Nov 15 '22 02:11

Oscar Mederos


For Adding At RunTime

Assembly can not be changed at run time so either you need to generate a you DLL at runtime and load it or you can use ExpandoObject as described in this SO question

For Adding At Compile Time

if you do not want to add code at runtime than you are exactly looking For CodeDom

like image 2
TalentTuner Avatar answered Nov 15 '22 01:11

TalentTuner