c# - Updating dynamically generated assembly -


i have following code dynamically generates assembly , classes based on edmmodel. working fine, bit confused on how can update assembly when model changes.

here current thoughts, either:

  • update current classes, adding/removing properties. adding new classes when needed.
  • create version of assembly, allowing me have 2 versions running @ same time (this approach preferable allow user access different versions of model, , mean current version still used while new 1 being generated)

is possible run 2 versions of same assembly way? possible update type has been created? doing right?

public class dynamicassembygenerator {     private idictionary<string, assemblybuilder> _assemblybuilders;     private idictionary<string, modulebuilder> _modulebuilders;     private idictionary<string, typebuilder> _typebuilders;     private idictionary<string, enumbuilder> _enumbuilders;     private idictionary<string, type> _types;      public void create(iedmmodel model)     {         _assemblybuilders = model.declarednamespaces.todictionary(declarednamespace => declarednamespace,             createassemblybuilder);         _modulebuilders = model.declarednamespaces.todictionary(declarednamespace => declarednamespace,             declarednamespace => createmodulebuilder(declarednamespace, _assemblybuilders[declarednamespace]));         _typebuilders = new dictionary<string, typebuilder>();         _enumbuilders = new dictionary<string, enumbuilder>();         _types = new dictionary<string, type>();          foreach (             var edmschemaelement in                 model.schemaelements.where(s => s.schemaelementkind == edmschemaelementkind.typedefinition))         {             if (_modulebuilders.containskey(edmschemaelement.namespace))             {                 createtype(model, edmschemaelement.fullname(), _modulebuilders[edmschemaelement.namespace]);             }         }          foreach (var assemblybuilder in _assemblybuilders.values)         {             assemblybuilder.save(assemblybuilder.getname().name + ".dll");         }          foreach (var value in _types.values)         {             var edmtype = model.finddeclaredtype(value.fullname);             model.setannotationvalue<clrtypeannotation>(edmtype, new clrtypeannotation(value));         }     }      private void createtype(iedmmodel model, string typename, modulebuilder modulebuilder)     {         if (_typebuilders.containskey(typename) || _enumbuilders.containskey(typename))         {             return;         }         var structuredtype = model.finddeclaredtype(typename) iedmstructuredtype;         if (structuredtype != null)         {             var entitytype = structuredtype iedmentitytype;              var typebuilder = createtypebuilder(structuredtype, model, modulebuilder);             _typebuilders.add(typename, typebuilder);              var constructorbuilder = createconstructor(typebuilder);             ilgenerator il = constructorbuilder.getilgenerator();             foreach (var edmproperty in structuredtype.declaredproperties)             {                 createproperty(edmproperty, model, typebuilder, il,                     entitytype != null && entitytype.hasdeclaredkeyproperty(edmproperty));             }              il.emit(opcodes.ret);              _types.add(typename, typebuilder.createtype());             return;         }          var enumtype = model.finddeclaredtype(typename) iedmenumtype;         if (enumtype != null)         {              var enumbuilder = createenumbuilder(typename, modulebuilder);             _enumbuilders.add(typename, enumbuilder);             foreach (var edmenummember in enumtype.members)             {                 var value = edmenummember.value edmintegerconstant;                 if (value != null)                 {                     createenumvalue(edmenummember.name, convert.toint32(value.value), enumbuilder);                 }             }             _types.add(typename, enumbuilder.createtype());             return;         }     }      private assemblybuilder createassemblybuilder(string assemblyname)     {         var appdomain = appdomain.currentdomain;         var assemblybuilder = appdomain.definedynamicassembly(new assemblyname(assemblyname), assemblybuilderaccess.runandsave);          return assemblybuilder;     }      private modulebuilder createmodulebuilder(string assemblyname, assemblybuilder assemblybuilder)     {         var modulebuilder = assemblybuilder.definedynamicmodule(assemblyname, assemblyname + ".dll");         return modulebuilder;     }      private typebuilder createtypebuilder(iedmstructuredtype type, iedmmodel model, modulebuilder modulebuilder)     {         var basetype = typeof(dynamicentitybase);         if (type.basetype != null)         {             var propertytype = edmlibhelpers.getclrtype(type.basetype, model);             if (propertytype == null)             {                 var schemaelement = model.finddeclaredtype(type.basetype.fulltypename());                 createtype(model, schemaelement.fullname(), _modulebuilders[schemaelement.namespace]);                 basetype = _types[schemaelement.fullname()];             }         }          return modulebuilder.definetype(type.fulltypename(), typeattributes.class | typeattributes.public, basetype);     }      private enumbuilder createenumbuilder(string typename, modulebuilder modulebuilder)     {         return modulebuilder.defineenum(typename, typeattributes.public, typeof(int));     }      private void createenumvalue(string name, int value, enumbuilder enumbuilder)     {         enumbuilder.defineliteral(name, value);     }      private void createproperty(iedmproperty edmproperty, iedmmodel model, typebuilder typebuilder, ilgenerator constructorilgenerator, bool iskey)     {         var propertytype = getpropertytype(edmproperty, model);          var propertyname = edmproperty.name;          fieldbuilder ffirst;          propertybuilder pfirst = createproperty(propertyname, propertytype, typebuilder, out ffirst);         setdefaultvalue(edmproperty, model, ffirst, constructorilgenerator);          if (iskey)         {             setpropertycustomattribute(pfirst, typeof(keyattribute));         }          if (edmproperty.vocabularyannotations(model).any(v => v.term.fullname() == corevocabularyconstants.computed))         {             setpropertycustomattribute(pfirst, typeof(computedattribute));         }          if (edmproperty.propertykind == edmpropertykind.navigation)         {             if (edmproperty.type.iscollection())             {                 createproperty(propertyname + "ids", typeof(ilist<string>), typebuilder, out ffirst);                 var listtype = typeof(list<string>);                 constructorilgenerator.emit(opcodes.ldarg_0);                 constructorilgenerator.emit(opcodes.newobj, listtype.getconstructor(new type[0]));                 constructorilgenerator.emit(opcodes.stfld, ffirst);             }             else             {                 createproperty(propertyname + "id", typeof(string), typebuilder, out ffirst);             }         }     }      private static propertybuilder createproperty(string propertyname, type propertytype, typebuilder typebuilder, out fieldbuilder fieldbuilder)     {         fieldbuilder = typebuilder.definefield("_" + propertyname, propertytype, fieldattributes.private);          propertybuilder pfirst = typebuilder.defineproperty(propertyname,                 propertyattributes.hasdefault, propertytype, null);          //getter         methodbuilder mfirstget = typebuilder.definemethod("get_" + propertyname, methodattributes.public |             methodattributes.specialname |             methodattributes.hidebysig, propertytype, type.emptytypes);         ilgenerator firstgetil = mfirstget.getilgenerator();          firstgetil.emit(opcodes.ldarg_0);         firstgetil.emit(opcodes.ldfld, fieldbuilder);         firstgetil.emit(opcodes.ret);          //setter         methodbuilder mfirstset = typebuilder.definemethod("set_" + propertyname, methodattributes.public |             methodattributes.specialname |             methodattributes.hidebysig, null, new type[] { propertytype });          ilgenerator firstsetil = mfirstset.getilgenerator();          firstsetil.emit(opcodes.ldarg_0);         firstsetil.emit(opcodes.ldarg_1);         firstsetil.emit(opcodes.stfld, fieldbuilder);         firstsetil.emit(opcodes.ret);          pfirst.setgetmethod(mfirstget);         pfirst.setsetmethod(mfirstset);          return pfirst;     }      private static void setpropertycustomattribute(propertybuilder propertybuilder, type attributetype)     {         var attributebuilder = new customattributebuilder(attributetype.getconstructor(new type[0]),             new object[0]);         propertybuilder.setcustomattribute(attributebuilder);     }      private type getpropertytype(iedmproperty edmproperty, iedmmodel model)     {         var edmpropertytype = getedmtype(edmproperty.type);         var propertytype = edmlibhelpers.getclrtype(edmpropertytype, model);         if (propertytype == null)         {             var schemaelement = model.finddeclaredtype(edmpropertytype.definition.fulltypename());             createtype(model, schemaelement.fullname(), _modulebuilders[schemaelement.namespace]);             propertytype = _typebuilders[schemaelement.fullname()];         }          if (edmproperty.type.iscollection())         {             var listtype = typeof(ilist<>);             propertytype = listtype.makegenerictype(propertytype);         }         return propertytype;     }      private iedmtypereference getedmtype(iedmtypereference type)     {         if (type.iscollection())         {             var collectiontype = type.ascollection();             return collectiontype.collectiondefinition().elementtype;         }         else         {             return type; ;         }     }      private void setdefaultvalue(iedmproperty property, iedmmodel model, fieldbuilder builder, ilgenerator constructorilgenerator)     {         if (!property.type.isnullable)         {             var propertytype = getpropertytype(property, model);             if (property.type.iscomplex())             {                 constructorilgenerator.emit(opcodes.ldarg_0);                 constructorilgenerator.emit(opcodes.newobj, propertytype.getconstructor(new type[0]));                 constructorilgenerator.emit(opcodes.stfld, builder);             }             else if (property.type.iscollection())             {                 var listtype = typeof(list<>);                 var collectiontype = listtype.makegenerictype(propertytype.getgenericarguments()[0]);                 constructorilgenerator.emit(opcodes.ldarg_0);                 constructorilgenerator.emit(opcodes.newobj, collectiontype.getconstructor(new type[0]));                 constructorilgenerator.emit(opcodes.stfld, builder);             }         }     }      private constructorbuilder createconstructor(typebuilder typebuilder)     {         constructorbuilder constructor = typebuilder.defineconstructor(                             methodattributes.public |                             methodattributes.specialname |                             methodattributes.rtspecialname,                             callingconventions.standard,                             new type[0]);          return constructor;     } } 

  • update current classes, adding/removing properties.

not possible. once call typebuilder.createtype() type created can't removed/modified.

  • adding new classes when needed.

possible without problems. can use types define in assemblybuilder without saving it, possible add new types.

  • create version of assembly, allowing me have 2 versions running @ same time

no problem here.

  • is possible run 2 versions of same assembly way?

it wouldn't same assembly .net... have in common? abstract concept "they same"? .net can't brain :-)


Comments

Popular posts from this blog

OpenCV OpenCL: Convert Mat to Bitmap in JNI Layer for Android -

android - org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope -

python - How to remove the Xframe Options header in django? -