tags:

views:

134

answers:

4

I have a string variable contain:

string classCode = "public class Person { public string Name{get;set;} }";

How can I create an instance of an object from the classCode ? like

object obj = CreateAnInstanceAnObject(classCode);
+5  A: 

You'll need to use CodeDom to compile an in-memory assembly, and then use reflection to create the type.

Here's a sample article on MSDN that walks through the process of code generation.

Once you've compiled the code, you can use Activator.CreateInstance to create an instance of it.

Reed Copsey
but i don't want to create second application in memory and I want create object in main app
Hamid
It doesn't create a second application - it creates an in-memory assembly (kind of like loading a DLL, but instead of loading it from disk, it generates it on the fly). You can use Activator.CreateInstance to create the object in memory.
Reed Copsey
Is it able to be dump? (memory dumping)
Hamid
Sure - you can use this to generate a DLL (if that's what you mean). Basically, it is just a normal .NET assembly, and can do anything you can do in .NET, but it's compiled on the fly and loaded into memory.
Reed Copsey
+1  A: 

Simple put you cannot do this in one line as you are attempting. It is possible to create an instance of an existing class via it's name and one of the overloads of Activator.CreateInstance.

What you are trying to achieve here though is quite different. You are attempting to both 1) define a new class type and 2) create an instance of it. Defining new metadata in the running process dynamically is very difficult to achieve with static languages like C#. It requires a significant amount of work that can't easily be put into a StackOverflow answer.

JaredPar
Why are people downvoting this? Jared's comments are all true. There's a reason I just linked to the code dom pages instead of trying to write out a full answer...
Reed Copsey
@Reed, thanks! Not sure either :(
JaredPar
Well, my upvote more than makes up for the downvotes - but it is odd... (I really wish downvoting required a comment with a reason. I hate not understanding why people are downvoting. :( )
Reed Copsey
A: 

The following project should guide you in what your trying to accomplish:

RunTime Code Compilation

However, if you are attempting to write code at runtime, you may want to rethink your architecture. You may be creating more of a headache for yourself than you need to be.

What are you trying to accomplish by creating this object?

George
I'm going to design an anti dump and anti crack lock checker class for my application which lock checker object must be create and work dynamically with dynamic structure.
Hamid
+2  A: 

Building on the answers from above, here is a working demo to generate, compile and instantiate a class from an in-memory assembly:

namespace DynamicCompilation
{
    using System;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    using System.Reflection;

    using Microsoft.CSharp;

    internal static class Program
    {
        private static void Main()
        {
            var ccu = new CodeCompileUnit();
            var cns = new CodeNamespace("Aesop.Demo");

            cns.Imports.Add(new CodeNamespaceImport("System"));

            var ctd = new CodeTypeDeclaration("Test")
            {
                TypeAttributes = TypeAttributes.Public
            };
            var ctre = new CodeTypeReferenceExpression("Console");
            var cmie = new CodeMethodInvokeExpression(ctre, "WriteLine", new CodePrimitiveExpression("Hello World!"));
            var cmm = new CodeMemberMethod
            {
                Name = "Hello",
                Attributes = MemberAttributes.Public
            };

            cmm.Statements.Add(cmie);
            ctd.Members.Add(cmm);
            cns.Types.Add(ctd);
            ccu.Namespaces.Add(cns);

            var provider = new CSharpCodeProvider();
            var parameters = new CompilerParameters
            {
                CompilerOptions = "/target:library /optimize",
                GenerateExecutable = false,
                GenerateInMemory = true
            };

            ////parameters.ReferencedAssemblies.Add("System.dll");

            var results = provider.CompileAssemblyFromDom(parameters, ccu);

            if (results.Errors.Count == 0)
            {
                var t = results.CompiledAssembly.GetType("Aesop.Demo.Test");
                var inst = results.CompiledAssembly.CreateInstance("Aesop.Demo.Test");
                t.InvokeMember("Hello", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, inst, null);
            }

            Console.ReadLine();
        }
    }
}
Jesse C. Slicer
Thanks Jesse, your source code is what I was lokking for ;)
Hamid
You're quite welcome, Hamid. Please feel free to vote up my answer and mark one of the ones that provided its basis as accepted. Thanks!
Jesse C. Slicer