[x]
Posted via EE Mobile

Search, ask, and monitor your questions on the go with EE Mobile. Visit Experts Exchange from your mobile device and never be out of touch again.

11/06/2009 at 05:43AM PST, ID: 24877791 | Points: 500
[x]
Attachment Details

Using Reflection.Emit, how can I flag a dynamically created property in an emitted class as WCF-DataMember?

Asked by farmed in WPF and Silverlight, Web Services and WCF, .NET Framework 3.x versions

Tags: Microsoft Silverlight WCF Windows Communication Foundation Reflection Typebuilder Emit Serialize Serializable DataMember Data Attribute

Hi,

regarding the topics question:

Following this code http://www.codeproject.com/KB/tabs/CustomPropGrid.aspx?df=100&forumid=32723&exp=0&select=864615 I made up some code to dynamically create a new instance of a new type.

I am dynamically reading a database (ColumnName + Value) and want to pass these two values x-times into a newly generated property using emit.

Example for Database (needs to be dynamically!):
ID--Name--SomeOther
4---Foo-----Bar
1---Foo2---Bar2

and so on.
So I am dynamically generating a new instance of type <randomNameHere> and adding properties this way:

                              Object1                                  Object2
Prop ID                   Value: 4                                 Value: 1
Prop Name             Value: Foo                             Value: Foo2
Prop SomeOther    Value: Bar                             Value: Bar2

I am doing this work on a WCF-Service, which consumes DSN and Select-Statement from a Silverlight-App.

And I need to pass this newly generated List<myDynObjectw/dynProps> back to silverlight.

Is this possible? I need to know, how to flag the Properties as WCF-DataMembers, or to get them serializable.

My WCF-Service is using ADO.NET Entity Framework, .NET 3.5. Silverlight is the latest release.
Visual Studio 2008, 2010 Beta2


--- Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
//WCF-Service 
// the service's method has a List<object> as return value, which is gracefully filled! No problems until communication with silverlight! 
//Emit 
public class PropertyAccessor
    {
        private ArrayList customObjects = new ArrayList(); 
        public object GenerateDynProp(List<MyProp> myprops)
        {
            Type newType = CreateType("test", myprops); 
            object newObj = CreateNewInstance(newType, myprops); 
            return newObj;
        } 
        private Type CreateType(string name, List<MyProp> props)
        {
            AssemblyName _assemblyName = new AssemblyName();
            _assemblyName.Name = name;
            AssemblyBuilder _assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.RunAndSave);
            
            ModuleBuilder _module = default(ModuleBuilder);
            _module = _assemblyBuilder.DefineDynamicModule(name + ".exe"); 
            TypeBuilder tb = _module.DefineType(name + "Type", TypeAttributes.Public | TypeAttributes.Serializable, typeof(clsDummy)); 
            foreach (MyProp item in props)
                AddProperty(item, tb); 
            return tb.CreateType();
        } 
        public void AddProperty(MyProp prop, TypeBuilder tb)
        { 
            //// Create some private fields
            FieldBuilder field1 = tb.DefineField("_" + prop.Name, prop.Type, FieldAttributes.Private); 
            //// Create some public properties
            PropertyBuilder field1Prop = tb.DefineProperty(prop.Name, PropertyAttributes.HasDefault, prop.Type, new Type[] { prop.Type }); 
            //Get
            MethodBuilder field1PropGet = tb.DefineMethod("Get" + prop.Name, MethodAttributes.Public, prop.Type, new Type[] { prop.Type }); 
            //Generate the IL
            ILGenerator field1PropGetIL = field1PropGet.GetILGenerator(); 
            field1PropGetIL.Emit(OpCodes.Ldarg_0);
            field1PropGetIL.Emit(OpCodes.Ldfld, field1);
            //load field1
            field1PropGetIL.Emit(OpCodes.Ret); 
            //Set
            MethodBuilder field1PropSet = tb.DefineMethod("Set" + prop.Name, MethodAttributes.Public, null, new Type[] { typeof(string) }); 
            //Generate the IL
            ILGenerator field1PropSetIL = field1PropSet.GetILGenerator(); 
            field1PropSetIL.Emit(OpCodes.Ldarg_0);
            field1PropSetIL.Emit(OpCodes.Ldarg_1);
            field1PropSetIL.Emit(OpCodes.Stfld, field1);
            //set field1
            field1PropSetIL.Emit(OpCodes.Ret); 
            //// map the methods to the Set/Get of the Field1 property
            field1Prop.SetGetMethod(field1PropGet);
            field1Prop.SetSetMethod(field1PropSet); 
        } 
        private object CreateNewInstance(Type newType, List<MyProp> props)
        {
            object newTypeInstance = Activator.CreateInstance(newType); 
            foreach (MyProp item in props)
            {
                newType.InvokeMember(item.Name, BindingFlags.SetProperty, null, newTypeInstance, new object[] { item.Value }); 
            } 
            return newTypeInstance;
        } 
    } 
    [Serializable()]
    public class MyProp
    {
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Name { get; set; } 
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public string Value { get; set; } 
        [global::System.Runtime.Serialization.DataMemberAttribute()]
        public Type Type { get; set; }
    } 
 
 
 
// Silverlight app 
// In here, the error occurs while calling base.EndInvoke<....>  
// clsDummy is an Empty class with Serializable()-Attribute 
 public System.Collections.ObjectModel.ObservableCollection<Shared.ServiceReference.clsDummy> EndExecuteSelect(System.IAsyncResult result) {
                object[] _args = new object[0];
                System.Collections.ObjectModel.ObservableCollection<Shared.ServiceReference.clsDummy> _result = ((System.Collections.ObjectModel.ObservableCollection<Shared.ServiceReference.clsDummy>)(base.EndInvoke("ExecuteSelect", _args, result)));
                return _result;
            }
 
Loading Advertisement...
20091111-EE-VQP-91 - Hierarchy / EE_QW_3_20080625