pauldotknopf / vroomjs-core

Cross-platform VroomJs with the .NET Core runtime.
MIT License
54 stars 6 forks source link

allow expandoObject #9

Open jchonc opened 8 years ago

jchonc commented 8 years ago

var obj = (dynamic)Newtonsoft.Json.JsonConvert.DeserializeObject<System.Dynamic.ExpandoObject>("{Name: 'Smith', Age: 23}"); using(var js = new VroomJs.JsEngine()) { var ctx = js.CreateContext(); ctx.SetVariable("obj1", obj); var result = ctx.Execute("if (obj1) { obj1.Age = 45; } "); var obj1 = ctx.GetVariable("obj1"); } Will fail with the error property not found on System.Dynamic.ExpandoObject: Age

But it works with

var obj = new Dictionary<string, object>(); obj["Name"] = "Smith"; obj["Age"] = 23;

Thanks in advance!

carlosmorcerf commented 6 years ago

try this:

    public static dynamic ConvertToJs(this ExpandoObject sourceObject)
    {

        var dictionary = sourceObject as IDictionary<string, object>;

        Int32 fieldOffset = 0;
        // get the public fields from the source object
        var sourceFields = dictionary.Keys;
        // get a dynamic TypeBuilder and inherit from the base type
        AssemblyName assemblyName
            = new AssemblyName("MyDynamicAssembly");
        AssemblyBuilder assemblyBuilder
            = AppDomain.CurrentDomain.DefineDynamicAssembly(
                assemblyName,
                AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBuilder
            = assemblyBuilder.DefineDynamicModule("MyDynamicModule");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("InternalType", TypeAttributes.Public);
        // add public fields to match the source object
        foreach (var sourceField in sourceFields)
        {
            FieldBuilder fieldBuilder
                = typeBuilder.DefineField(
                    sourceField,
                    dictionary[sourceField]?.GetType() ?? typeof(string),
                    FieldAttributes.Public);
            fieldBuilder.SetOffset(fieldOffset);
            fieldOffset++;
        }
        // create the dynamic class
        var type =  typeBuilder.CreateType();

        return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(sourceObject), type);

    }