Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a C# object at run time?

Tags:

c#

object

dynamic

We have XML code stored in a single relational database field to get around the Entity / Attribute / Value database issues, however I don't want this to ruin my Domain Modeling, DTO, and Repository sunshine. I cannot get around the EAV/CR content, but I can choose how to store it. Question is how would I use it?

How could I turn the XML metadata in to a class / object at run time in C#?

For example:

XML would describe that we have a food recipe which has various attributes, but usually similar, and one or more attributes about making the food. The food itself can literally be anything and have any type of crazy preparation. All attributes are searched and may link to existing nutritional information.

// <-- [Model validation annotation goes here for MVC2]
public class Pizza {
     public string kind  {get; set;}
     public string shape {get; set;}
     public string city  {get; set;}
     ...
}

and in the ActionMethod:

makePizzaActionMethod (Pizza myPizza) {
    if (myPizza.isValid() ) {  // this is probably ModelState.isValid()...
        myRecipeRepository.Save( myPizza);
        return View("Saved");
    }
    else
        return View();
}
like image 334
Zachary Scott Avatar asked Feb 09 '10 03:02

Zachary Scott


2 Answers

Is ExpandoObject what you're looking for?

Represents an object whose members can be dynamically added and removed at run time.

like image 72
Foole Avatar answered Oct 09 '22 11:10

Foole


Check out the System.Reflection.Emit namespace.

You Start with an AssemblyBuilder class from AppDomain.CurrentDomain

AssemblyBuilder dynAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly("dynamic.dll",
                                                                            AssemblyBuilderAccess.RunAndSave);

From there you have to build a ModuleBuilder, from which you can build a TypeBuilder.

Check out the AssmblyBuilder reference for an example.

You can save the generated assembly, or you can just use it in memory. Be warned though, that you will get heavy into reflection to use these dynamic types.

EDIT:

Below is an example of how to iterate through the properties:

AssemblyName aName = new AssemblyName("dynamic");
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mb = ab.DefineDynamicModule("dynamic.dll");
TypeBuilder tb = mb.DefineType("Pizza");
//Define your type here based on the info in your xml
Type theType = tb.CreateType();

//instanciate your object
ConstructorInfo ctor = theType.GetConstructor(Type.EmptyTypes);
object inst = ctor.Invoke(new object[]{});

PropertyInfo[] pList = theType.GetProperties(BindingFlags.DeclaredOnly);
//iterate through all the properties of the instance 'inst' of your new Type
foreach(PropertyInfo pi in pList)
    Console.WriteLine(pi.GetValue(inst, null));
like image 33
Grant Back Avatar answered Oct 09 '22 10:10

Grant Back