/// <summary> /// Gets the Setting object tied to the string. If there is no Setting object, one will be created with the defaultValue /// </summary> /// <param name="key">The name of the setting object</param> /// <param name="defaultvalue">if there is no Setting object tied to the string, a Setting will be created with this as its Value</param> /// <returns>The Setting object tied to the string</returns> public Setting GetSetting(string key, object defaultvalue) { if(settings[key]==null) { settings[key]=new Setting(defaultvalue, null, null, null,null); ((Setting)settings[key]).Name=key; } return (Setting)settings[key]; }
/// <summary> /// emits a generic get/set property in which the result returned resides in a hashtable whos key is the name of the property /// </summary> /// <param name="pb">PropertyBuilder used to emit</param> /// <param name="tb">TypeBuilder of the class</param> /// <param name="hash">FieldBuilder of the hashtable used to store the object</param> /// <param name="po">PropertyObject of this property</param> private void emitProperty(TypeBuilder tb,FieldBuilder hash,Setting s,string name) { //to figure out what opcodes to emit, i would compile a small class having the functionality i wanted, and viewed it with ildasm. //peverify is also kinda nice to use to see what errors there are. //define the property first PropertyBuilder pb = tb.DefineProperty(name,PropertyAttributes.None,s.Value.GetType(),new Type[] {}); Type objType = s.Value.GetType(); //now we define the get method for the property MethodBuilder getMethod = tb.DefineMethod("get_"+name,MethodAttributes.Public,objType,new Type[]{}); ILGenerator ilg = getMethod.GetILGenerator(); ilg.DeclareLocal(objType); ilg.Emit(OpCodes.Ldarg_0); ilg.Emit(OpCodes.Ldfld,hash); ilg.Emit(OpCodes.Ldstr,name); ilg.EmitCall(OpCodes.Callvirt,typeof(Hashtable).GetMethod("get_Item"),null); if(objType.IsValueType) { ilg.Emit(OpCodes.Unbox,objType); if(typeHash[objType]!=null) ilg.Emit((OpCode)typeHash[objType]); else ilg.Emit(OpCodes.Ldobj,objType); } else ilg.Emit(OpCodes.Castclass,objType); ilg.Emit(OpCodes.Stloc_0); ilg.Emit(OpCodes.Br_S,(byte)0); ilg.Emit(OpCodes.Ldloc_0); ilg.Emit(OpCodes.Ret); //now we generate the set method for the property MethodBuilder setMethod = tb.DefineMethod("set_"+name,MethodAttributes.Public,null,new Type[]{objType}); ilg = setMethod.GetILGenerator(); ilg.Emit(OpCodes.Ldarg_0); ilg.Emit(OpCodes.Ldfld,hash); ilg.Emit(OpCodes.Ldstr,name); ilg.Emit(OpCodes.Ldarg_1); if(objType.IsValueType) ilg.Emit(OpCodes.Box,objType); ilg.EmitCall(OpCodes.Callvirt,typeof(Hashtable).GetMethod("set_Item"),null); ilg.Emit(OpCodes.Ret); //put the get/set methods in with the property pb.SetGetMethod(getMethod); pb.SetSetMethod(setMethod); //if we specified a description, we will now add the DescriptionAttribute to our property if(s.Description!=null) { ConstructorInfo ci = typeof(DescriptionAttribute).GetConstructor(new Type[]{typeof(string)}); CustomAttributeBuilder cab = new CustomAttributeBuilder(ci,new object[]{s.Description}); pb.SetCustomAttribute(cab); } //add a CategoryAttribute if specified if(s.Category!=null) { ConstructorInfo ci = typeof(CategoryAttribute).GetConstructor(new Type[]{typeof(string)}); CustomAttributeBuilder cab = new CustomAttributeBuilder(ci,new object[]{s.Category}); pb.SetCustomAttribute(cab); } }
private void xp_OnElementEnd(string name) { if (name == "Field") settings[0][fieldName] = new Setting(value, obj, field, description, category, handleEvent); }