I am trying to use a dynamically generated type as the source of one business rule editor called codeeffects (www.codeeffects.com), however I get this exception
Could not find or load assembly "tmpAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null". Error message: Could not load file or assembly 'tmpAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. (Error S103)
Index action in the controller:
[HttpGet] public ActionResult Index() { IMyInterface myObject = (IMyInterface)ObjectBuilder.CreateOurNewObject(); Type t = myObject.GetType(); ViewBag.Rule = RuleModel.Create(t); return View(); }
and the method that creates the new object
public static object CreateOurNewObject() { string _xml = "<root>" + "<column name=\"Name\">Miron</column>" + "<column name=\"LastName\">Abramson</column>" + "<column name=\"Blog\">www.blog.mironabramson.com</column>" + "</root>"; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(_xml); // create a dynamic assembly and module AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "tmpAssembly"; System.Reflection.Emit.AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule"); // create a new type builder TypeBuilder typeBuilder = module.DefineType("BindableRowCellCollection", TypeAttributes.Public | TypeAttributes.Class); typeBuilder.AddInterfaceImplementation(typeof(IMyInterface)); // Loop over the attributes that will be used as the properties names in out new type foreach (XmlNode node in xmlDoc.SelectSingleNode("root").ChildNodes) { string propertyName = node.Attributes["name"].Value; // Generate a private field FieldBuilder field = typeBuilder.DefineField("_" + propertyName, typeof(string), FieldAttributes.Private); // Generate a public property PropertyBuilder property = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, typeof(string), new Type[] { typeof(string) }); // The property set and property get methods require a special set of attributes: MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig; // Define the "get" accessor method for current private field. MethodBuilder currGetPropMthdBldr = typeBuilder.DefineMethod("get_value", GetSetAttr, typeof(string), Type.EmptyTypes); // Intermediate Language stuff... ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator(); currGetIL.Emit(OpCodes.Ldarg_0); currGetIL.Emit(OpCodes.Ldfld, field); currGetIL.Emit(OpCodes.Ret); // Define the "set" accessor method for current private field. MethodBuilder currSetPropMthdBldr = typeBuilder.DefineMethod("set_value", GetSetAttr, null, new Type[] { typeof(string) }); // Again some Intermediate Language stuff... ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator(); currSetIL.Emit(OpCodes.Ldarg_0); currSetIL.Emit(OpCodes.Ldarg_1); currSetIL.Emit(OpCodes.Stfld, field); currSetIL.Emit(OpCodes.Ret); // Last, we must map the two methods created above to our PropertyBuilder to // their corresponding behaviors, "get" and "set" respectively. property.SetGetMethod(currGetPropMthdBldr); property.SetSetMethod(currSetPropMthdBldr); } // Generate our type Type generetedType = typeBuilder.CreateType(); // Now we have our type. Let create an instance from it: object generetedObject = Activator.CreateInstance(generetedType); // Loop over all the generated properties, and assign the values from our XML: PropertyInfo[] properties = generetedType.GetProperties(); int propertiesCounter = 0; // Loop over the values that we will assign to the properties foreach (XmlNode node in xmlDoc.SelectSingleNode("root").ChildNodes) { string value = node.InnerText; properties[propertiesCounter].SetValue(generetedObject, value, null); propertiesCounter++; } //Yoopy ! Return our new genereted object. return generetedObject; }