Showing posts with label .Net Framework. Show all posts
Showing posts with label .Net Framework. Show all posts

Sunday, 8 April 2012

Dynamically compiling code in memory using the CodeDomProvider

Recently I had to dynamically load some code from a text file and execute it at run time in memory. The CodeDomProvider seemed to do the trick nicely as you can see below. You can generate an assembly in memory using the CompileAssemblyFromSource method like I have done or use it's CompileAssemblyFromFile or CompileAssemblyFromDom counterparts.
using System;
using System.Collections.Generic;
using System.Linq;
 
using Microsoft.CSharp;
using System.CodeDom.Compiler;
 
namespace DynamicCompilerConsoleApp
{
    
    public interface IConsoleWriter
    {
        void WriteToConsole(string message);
    }
    
    public class DynamicAssembyExecution
    {
        public static void DynamicCodeExecution()
        {
            const string code = @"using System;
                                  using DynamicCompilerConsoleApp;
                            namespace LoadXmlTestConsole
                            {
                                public class ConsoleWriter : IConsoleWriter
                                {
                                    public void WriteToConsole(string message)
                                    {
                                        Console.WriteLine(message);
                                    }
                                }
                            }";
 
            CodeDomProvider codeCompiler =
                new CSharpCodeProvider(new Dictionary<string, string> {{"CompilerVersion", "v4.0"}});
            // Create the optional compiler parameters
            CompilerParameters compilerParameters = new CompilerParameters
                                                        {
                                                            GenerateExecutable = false,
                                                            GenerateInMemory = true,
                                                            WarningLevel = 3,
                                                            TreatWarningsAsErrors = false,
                                                            CompilerOptions = "/optimize"
                                                        };
 
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                compilerParameters.ReferencedAssemblies.Add(assembly.Location);    
            }
 
            // Compile the string containing the code, using the provided set of parameters
            CompilerResults compilerResults = codeCompiler.CompileAssemblyFromSource(compilerParameters,
                                                                                        code);
            //Display any compiler errors in the console window
            if (compilerResults.Errors.HasErrors)
                foreach (string line in compilerResults.Output)
                    Console.WriteLine(line);
 
            // Get the required type out of the assembly
            Type consoleWriterType =
                compilerResults.CompiledAssembly.GetTypes().SingleOrDefault(
                    lt => lt.GetInterface(typeof (IConsoleWriter).Name) != null);
              
            // create an instance of the type
            IConsoleWriter consoleWriter = (IConsoleWriter)Activator.CreateInstance(consoleWriterType);
                
            // execute the compiled code
            consoleWriter.WriteToConsole("hello world");
            
        }
    }
}

Sunday, 12 June 2011

Text search and replace in large files using .net framework

When performing search and replace in large text files you should avoid loading the entire file into memory and rather make use of the StreamReader/StreamWriter classes provided by the .Net Framework. I thought I would share this short code snippet below which makes use of these two useful classes.


using System.IO;
namespace LoadXmlTestConsole
{
    public class TextReplaceConsoleApp
    {
        public static void Main()
        {
            // File to perform search and replace on
            string inputFileLocation = @"D:\largeTextFileInput.xml";

            // File to create with replaced text
            string outputFileLocation = @"D:\largeTextFileOutput.xml";

            using (StreamReader reader = new StreamReader(File.Open(inputFileLocation, FileMode.Open)))
            {
                using (StreamWriter writer = new StreamWriter(File.Open(outputFileLocation, FileMode.Create)))
                {
                    ReplaceInStreams(reader, writer);
                }
            }
        }

        private static void ReplaceInStreams(StreamReader reader, StreamWriter writer)
        {
            while (reader.Peek() != -1)
            {
                string line = reader.ReadLine();
                // If search text found
                if (line.IndexOf("Male") > -1)
                {
                    //Perform text replace on line
                    line = line.Replace("Male", "Alien");
                    writer.WriteLine(line);
                }
                else
                {
                    writer.WriteLine(line);
                }
            }
        }
    }
}