|
using System;
using System.Collections.Generic;
using System.Text;
using System.CodeDom;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.IO;
namespace DynamicCodeGeneration.CodeGenerator
{
class CSharpGenerator : IGenerator
{
private string _code;
/// <summary>
///
/// </summary>
/// <returns></returns>
private string BuildGeneratedCode()
{
try
{
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeCompiler codeCompiler = codeProvider.CreateCompiler();
CompilerParameters parameters = new CompilerParameters();
parameters.ReferencedAssemblies.Add("DynamicCodeGeneration.Base.dll");
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("DynamicCodeGeneration.CustomAttributes.dll");
parameters.GenerateInMemory = false;
CompilerResults results = codeCompiler.CompileAssemblyFromSource(parameters, this.Code);
if (results.Errors.HasErrors)
{
string errorMessage = "";
errorMessage = results.Errors.Count.ToString() + " Errors:";
for (int x = 0; x < results.Errors.Count; x++)
{
errorMessage = errorMessage + "\r\nLine: " + results.Errors[x].Line.ToString() + " - " + results.Errors[x].ErrorText;
}
return errorMessage;
}
return results.PathToAssembly;
}
catch (Exception ex)
{
throw new Exception("Error while trying to build generated code.", ex);
}
}
#region IGenerator Members
/// <summary>
///
/// </summary>
/// <param name="assemblyAuthorName"></param>
/// <param name="classAuthorName"></param>
/// <param name="methodAuthorName"></param>
/// <returns>Generated Code</returns>
public string GenerateAssembly(string assemblyAuthorName, string classAuthorName, string methodAuthorName)
{
try
{
#region Unit
CodeCompileUnit unit = new CodeCompileUnit();
CodeAttributeArgument[] arguments = new CodeAttributeArgument[2];
arguments[0] = new CodeAttributeArgument(new CodePrimitiveExpression(assemblyAuthorName));//Create parameter for attribute
arguments[1] = new CodeAttributeArgument(new CodeSnippetExpression("DynamicCodeGeneration.CustomAttributes.GenerationMode.CodeDOM"));
CodeAttributeDeclaration assemblyLevelAttribute = new CodeAttributeDeclaration(new CodeTypeReference("DynamicCodeGeneration.CustomAttributes.AssemblyLevelAttribute"), arguments);//Create attribute to be added to assembly
unit.AssemblyCustomAttributes.Add(assemblyLevelAttribute);
unit.ReferencedAssemblies.Add("DynamicCodeGeneration.Base.dll");
unit.ReferencedAssemblies.Add("System.dll");
unit.ReferencedAssemblies.Add("DynamicCodeGeneration.CustomAttributes.dll");
unit.ReferencedAssemblies.Add("Microsoft.Crm.SdkTypeProxy.dll");
#endregion
#region Namespace
CodeNamespace customEntityRoot = new CodeNamespace("DerivedRoot");//Create a namespace
unit.Namespaces.Add(customEntityRoot);
customEntityRoot.Imports.Add(new CodeNamespaceImport("System"));//Add references
customEntityRoot.Imports.Add(new CodeNamespaceImport("DynamicCodeGeneration.Base"));//Add references
customEntityRoot.Imports.Add(new CodeNamespaceImport("DynamicCodeGeneration.CustomAttributes"));//Add references
#endregion
#region Class
CodeTypeDeclaration derived = new CodeTypeDeclaration("Derived");//Create class
customEntityRoot.Types.Add(derived);//Add the class to namespace defined above
CodeConstructor derivedClassConstructor = new CodeConstructor();//Create constructor
derivedClassConstructor.Attributes = MemberAttributes.Public;
derived.Members.Add(derivedClassConstructor);//Add constructor to class
CodeAttributeArgument argument = new CodeAttributeArgument(new CodePrimitiveExpression(classAuthorName));
CodeAttributeDeclaration classLevelAttribute = new CodeAttributeDeclaration(new CodeTypeReference("DynamicCodeGeneration.CustomAttributes.ClassLevelAttribute"), argument);//Create attribute to be added to class
derived.CustomAttributes.Add(classLevelAttribute);
derived.BaseTypes.Add(new CodeTypeReference("Base"));
#endregion
#region Method
CodeMemberMethod derivedMethod = new CodeMemberMethod();
derivedMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override; //Make this method an override of base class's method
derivedMethod.Comments.Add(new CodeCommentStatement(new CodeComment("TestComment")));
derivedMethod.Name = "Method";
derivedMethod.ReturnType = new CodeTypeReference(typeof(void));
arguments = new CodeAttributeArgument[2];
arguments[0] = new CodeAttributeArgument(new CodeSnippetExpression("ComplexityLevel.SuperComplex"));//Create parameter for attribute
arguments[1] = new CodeAttributeArgument(new CodePrimitiveExpression(methodAuthorName));
CodeAttributeDeclaration methodLevelAttribute = new CodeAttributeDeclaration(new CodeTypeReference("DynamicCodeGeneration.CustomAttributes.MethodLevelAttribute"), arguments);//Create attribute to be added to method
derivedMethod.CustomAttributes.Add(methodLevelAttribute);//Add attribute to method
CodeSnippetStatement code = new CodeSnippetStatement("base.Method();");
derivedMethod.Statements.Add(code);
derived.Members.Add(derivedMethod);//Add method to the class
#endregion
#region Generate Code
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeGenerator codeGenerator = codeProvider.CreateGenerator();
StringBuilder generatedCode = new StringBuilder();
StringWriter codeWriter = new StringWriter(generatedCode);
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";//Keep the braces on the line following the statement or declaration that they are associated with
codeGenerator.GenerateCodeFromCompileUnit(unit, codeWriter, options);
#endregion
this.Code = generatedCode.ToString();
return BuildGeneratedCode();
}
catch (Exception ex)
{
throw new Exception("Error while trying to generate code.", ex);
}
}
/// <summary>
///
/// </summary>
public string Code
{
get { return _code; }
set { _code = value; }
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I work with Proteans Software Solutions. Interests include software architecture, design patterns, agile, scrum development, automated acceptance testing, books, music, travel, movies...