3

I have a stored procedure which accepts the table name, then it reads the table structure and returns me the table structure in the form of a class definition in a string.

E.g.:

string myString = 
 "
   public class TableName
   { 
     public int Column1 { get; set; } 
   }
 "

Is it possible a create a Class/Type from the string containing the class definition ? For eg:-

Type type = GenerateType(myString);

I have to pass this type variable to my further piece of code so please help me to create class/type from the string containing the class definition.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Ankur Arora
  • 194
  • 3
  • 15
  • 3
    [Try Roslyn](https://github.com/dotnet/roslyn). But what do you plan to do with instances of a class whose type is unknown at compile time? – 15ee8f99-57ff-4f92-890c-b56153 Jan 02 '18 at 14:08
  • Are you creating some type of [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping)? – Zohar Peled Jan 02 '18 at 14:11
  • 2
    I think you are actually looking for *serialization*. There are many ways to achieve this, it depends on your needs and the complexity of your classes. Usually, serializing to/from Json is sufficient for many cases. – Rob Jan 02 '18 at 14:12
  • Create new type at runtime is very complex do you really need that? I suggest you to find alternatives maybe [dynamic](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic) or [ExpandoObject](https://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject(v=vs.110).aspx) can help? If you find you have to create a new type give [TypeBuilder](https://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder(v=vs.110).aspx) a look. – YuvShap Jan 02 '18 at 14:43
  • This has to be one of the very strangest things I've ever seen. Ever. If I'm getting this straight, it's C# code that defines a class that describes a table and columns, while itself being stored in a column in a table. Please don't do this. – Scott Hannen Jan 02 '18 at 16:10
  • @ScottHannen, you have understood half of the requirement correctly i.e. my class structure and table structure is same. You can visualize it as an ORM generated class but it is not stored in a column in the table. I have an SP which reads the table definition from system table and then concatenates the information to look like class structure and then returns that concatenated string . – Ankur Arora Jan 02 '18 at 16:43
  • 1
    This is going to sound like I'm being facetious, but I'm not. Execute the stored procedure, copy the class definition it generates, and then paste that into a class file in your project. Then you will have achieved what you asked in your question - you will have created a type to hold the output of the stored procedure. – Scott Hannen Jan 02 '18 at 16:50
  • @ScottHannen I cannot manually copy the class definition and paste it into a class file. This has to be done through the code dynamically. Here I am creating the class dynamically based on the table structure. This dynamically created class will be consumed by my further piece of code – Ankur Arora Jan 03 '18 at 05:23

1 Answers1

7

You can use the CSharpCodeProvider to compile your result at runtime and then use the Activator - Class to create an object from your generated code.

// compile your piece of code to dll file
Microsoft.CSharp.CSharpCodeProvider cSharpCodeProvider = new Microsoft.CSharp.CSharpCodeProvider();
System.CodeDom.Compiler.CompilerParameters compilerParameters = new System.CodeDom.Compiler.CompilerParameters();
compilerParameters.GenerateInMemory = true;
compilerParameters.GenerateExecutable = false;
System.CodeDom.Compiler.CompilerResults cResult = cSharpCodeProvider.CompileAssemblyFromSource(compilerParameters, "using System; namespace Tables { 'put here your class definition' }");

// then load your dll file, get type and object from class
Assembly assembly = cResult.CompiledAssembly;
Type myTableType = assembly.GetType("Tables.Tablename");
var finalResult = Activator.CreateInstance(myTableType);
Craylen
  • 313
  • 2
  • 12
  • Thank you very much. This works just perfectly. Saved my time – Ankur Arora Jan 02 '18 at 17:08
  • Getting an issue in this line 'Assembly assembly = cResult.CompiledAssembly'. This works if I am in the executing assembly (For eg:- Main method is in the same assembly) but in my scenario this code is inside a DLL and I am referring this DLL in my startUp project. In this case I am getting exception 'Cannot load file or assembly' – Ankur Arora Jan 04 '18 at 06:52
  • Check your cResult.Errors => i suggest your code doesn't compile – Craylen Jan 04 '18 at 08:17
  • Yes, There was an error in cResult. Fixed and working now. Many thanks – Ankur Arora Jan 04 '18 at 09:42