Dynamic Code in C# Reply

co-authored by Joseph Dotson

2_bgWe are working on a project where the data access methodology for the application was defined and provided by the client.  While this approach accomplishes the tasks of accessing data in SQL Server we found that we were duplicating code making small changes to new files but largely repeating code to access new tables in the database.  We decided to look at dynamic code in C# to solve this problem and reduce redundancy in the code base.

Detailed below will be some sample code that could be used to dynamically create code on the fly handled by the CLR at run time. The solution uses T4 template code generation to generate a sample class that might be repeated throughout the project.

First we created a T4 template file named “RunTimeTextTemplate1.tt” in our solution. The contents of this file will get loaded and executed dynamically at runtime:

 

#@ template language="C#" #
#@ assembly name="System.Core" #
#@ import namespace="System.Linq" #
@# import namespace="System.Text" #
#@ import namespace="System.Collections.Generic" #
using System;
namespace ConsoleApplication1
{
     class #= Name # : ITest
     {

          public void Run()
          {
               Console.WriteLine("test");
          {
     }
}

We then created the following class that will receive the code from the above T4 template:

public partial class RuntimeTextTemplate1
     {
          public string Name { get; set; }
          public RuntimeTextTemplate1(string data)
          {
               Name = data;
          }
     }

When TransformText() method is called is loads the code in the template as seen in debug Text Visualizer below to be loaded and executed at run time.

image1.png

Below is the commented working example, start to finish, of how all this works.

static void Main(string[] args)
     {

          string name = "MyCLRGeneratedClass";
          //Pass the class to the template
          RuntimeTextTemplate1 x = new RuntimeTextTemplate1(name);

          //This will load/transform the text contained in RunTimeTemplate1.tt
          //Represents the code we would be duplicating
          string TheCodeWeDoNotWantToRepeat = x.TransformText();

          //Load all assemblies required to run
          CSharpCodeProvider provider = new CSharpCodeProvider();
          CompilerParameters parameters = new CompilerParameters();
          foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
          {
               try
               {
                    string location = assembly.Location;
                    parameters.ReferencedAssemblies.Add(location);
               }
               catch (Exception)
               {

               }
          {
//passes all required assemblies and the code form the template for the CLR to run for us on the fly.
          CompilerResults results = provider.CompileAssemblyFromSource(parameters, TheCodeWeDoNotWantToRepeat);

//Create instance of our console app
          ITest instance =
(ITest)Activator.CreateInstance(results.CompiledAssembly.GetType("ConsoleApplication1." +
name));
          //Make the call to run the code from our template
          instance.Run();
     }
}

This approach will allow us to create T4 templates that will have the majority of the code we need in our data access classes that we don’t want to duplicate and we can change any part of the dynamically loaded code to suit our needs.  For example, we passed in the name of the class to the template and the CLR replaced it for us seen here in the t4 template:

image2.png

This will allow us to dynamically set connection strings or the name of a specific entity we want to perform CRUD operations on using the same code but varying the name of the entity or table we are working with. This approach allows us to swap entire code blocks if needed. We can now use a single template of data access logic to work with different tables without literally copying and pasting code.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s