tags:

views:

351

answers:

3

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();
}
A: 

EDIT: This does not address the original poster's question.

I think that this may be possible using XAML. I would generate a XAML file, and then load it dynamically using XamlReader.Load() create an object at run-time with the properties I want.

There is an interesting article to read on the subject of XAML as an object serialization framework here. For more information on XAML namespaces see here.

cdiggins
@cdiggins: -1: I can't imagine how XAML will help. I'll remove the downvote if you assist my imagination.
John Saunders
Added some clarification. You can create dynamic objects with XamlReader.Load(), isn't this going to work Dr. Zim's case? Or am I missing something?
cdiggins
Can you give an example? Because I don't believe you.
John Saunders
Button readerLoadButton = (Button)XamlReader.Load(xmlReader);It does create objects from xml, however it may be limited to the Xaml namespace though.
Dr. Zim
There still needs to be a class defined for the XamlReader to materialise -- e.g. a Pizza class. XAML won't create the class for you, but it will create instances of the class from XML once the class exists. And I think Dr Zim's problem is more around the creation of the class than around the reading in from XML.
itowlson
Dr Zim: XAML is not limited to the XAML namespace (I've used XamlReader successfully to read in e.g. business rules), but you would need to provide your own namespace mappings for things that aren't in the XAML namespace.
itowlson
I'm not an expert, but I do know that XAML is a generic object serialization framework (not just limited to WPF). I am looking into rolling a demo but I'll add some links to my answer.
cdiggins
@itowlson - I upvoted your comment. You nailed it: creating a class from the XML mini-schema.
Dr. Zim
+6  A: 

Is ExpandoObject what you're looking for?

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

Foole
+1 for using ExpandoObject in a sentence! What class names will MS come up with next :) (oh, and a good idea :P This object is only available in .net 4.0 from memory).
Russell
Wow. Now that is a good application of knowledge to a particular problem. I am going to let the question ride for a bit, but this answer is very nice.
Dr. Zim
I find this very disturbing, personally. But I suppose this isn't the place to debate the merits of this "thing".
Noon Silk
Welcome to the brave new world of dynamic c#.
Isaac Cambron
+2  A: 

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));
Grant Back
I still don't see how such a class could be used, since code does not know about the additional properties.
John Saunders
You can iterate through the Properties of the new type using the associated Type class I will add an example above.
Grant Back