Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically create and set members/properties of class at runtime

How can I create and set members/properties of a class dynamically at runtime.

Ref: http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.trygetmember(v=vs.110).aspx

I tried to modify the idea to suit my requirements but unable to do it.

I am required to set the class members at runtime, means I would fetch the Key and Value from the database and my class will be completely dynamic with no members defined before runtime, but all of them is fetched from database during runtime.

So here goes my code (Taken from MSDN):

public class DynamicObjDictionary : DynamicObject
{
    // The inner dictionary.
    Dictionary<string, object> dictionary = new Dictionary<string, object>();
    public int Count
    {
        get{return dictionary.Count;}
    }

public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        string name = binder.Name.ToLower();
        return dynDict.TryGetValue(name, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        dynDict[binder.Name.ToLower()] = value;
        return true;
    }
 }
}

The code that initializes and defines the members/properties of the class

dynamic DynObj = new DynamicObjDictionary();
        DataSet ds = new DataSet();
        ds = GetObjectProperties() // returns dataset having the properties as key and value pair;
        if (ds.Tables["PropTable"].Rows.Count > 0)
        {
            foreach (DataRow dr in ds.Tables["PropTable"].Rows)
            {
                string KeyName = dr["KeyName"].ToString();
                string ValueName= dr["ValueName"].ToString();
                //---I want that in place of fldName the actual value from dr is added to the class - currently it returns DynObj.KeyName only.
                DynObj.KeyName = ValueName;
                // Means if current dr["KeyName"].ToString() has "Property1"
                // And dr["ValueName"].ToString() has "PropertyValue"
                // The DynObj should be like DynObj.Property1 = "PropertyValue" 
            }
        }

And another problem is that I want all the properties to be set after the above initialization so that I can access them like a class object that is hard-coded. Current code only retails the last property i.e. the value of the last row of the dataset.

like image 956
Cyberpks Avatar asked Dec 16 '13 10:12

Cyberpks


1 Answers

Either add a dictionary-based API, or use an implementation that already has it. Frankly ExpandoObject would work fine, and has an IDictionary<string,object> API built in.

var obj = new ExpandoObject();
DataSet ds = GetObjectProperties() // returns dataset having the properties as key and value pair;
if (ds.Tables["PropTable"].Rows.Count > 0)
{
    foreach (DataRow dr in ds.Tables["PropTable"].Rows)
    {
        string KeyName = dr["KeyName"].ToString();
        string ValueName= dr["ValueName"].ToString();
        obj[KeyName] = ValueName;
    }
}
dynamic DynObj = obj;
// ...
like image 166
Marc Gravell Avatar answered Sep 20 '22 02:09

Marc Gravell