/// <summary> /// Crea oggetto del tipo definito senza schema (es. tipo lista) /// </summary> /// <param name="type"></param> /// <returns></returns> internal object CreateDaoNoSchemaObj(Type type) { try { //Crea istanza ProxyEntryDao oTypeEntry = this.GetDaoEntry(type); //Istanzia object o = oTypeEntry.Create(); //Ritorna return(o); } catch (KeyNotFoundException) { throw new TypeFactoryException("Tipo {0} non trovato. E' possibile che si siano verificati errori in fase di generazione schema.", type.Name); } catch (Exception ex) { if (ex.InnerException != null) { throw ex.InnerException; } else { throw; } } }
/// <summary> /// Crea un oggetto specificando se valorizzare o meno il dataschema /// </summary> /// <param name="type"></param> /// <param name="withData"></param> /// <returns></returns> internal object CreateDaoObj(Type type, bool withData) { try { //Crea istanza ProxyEntryDao oTypeEntry = this.GetDaoEntry(type); //Istanzia var o = oTypeEntry.Create() as DataObjectBase; //Imposta schema su oggetto o.mClassSchema = oTypeEntry.ClassSchema; o.ObjectRefId = Interlocked.Increment(ref _ObjeRefIdCounter); if (withData) { o.mDataSchema = new Schema.Usage.DataSchema(o.mClassSchema.Properties.Count, o.mClassSchema.ObjCount); } //Ritorna return(o); } catch (KeyNotFoundException) { throw new TypeFactoryException("Tipo {0} non trovato. E' possibile che si siano verificati errori in fase di generazione schema.", type.Name); } catch (Exception ex) { if (ex.InnerException != null) { throw ex.InnerException; } else { throw; } } }
/// <summary> /// Crea i tipi modificati per l'assembly specificato /// </summary> /// <param name="outProxy"></param> internal static void BuildDaoProxyFromAssembly(ProxyAssemblyCache.ProxyAssemblyDao outProxy) { DynAssemblyProxy dapx = initProxyAssembly(outProxy.SrcAss); //Imposta oggetto output base outProxy.DynAss = dapx.PxAssemblyBuilder; //Controlla ogni tipo definito nell'Assembly foreach (Type tOriginal in outProxy.SrcAss.GetTypes()) { bool bCreateSchema = tOriginal.IsSubclassOf(TYPE_DATA_OBJ_BASE); bool bIsBdoItem = (bCreateSchema || tOriginal.IsSubclassOf(TYPE_DATA_LIST_BASE)); PropertyInfo[] arrPropInfo = null; //Se non BDO allora skip if (!bIsBdoItem) { continue; } //Ok, BDO try { long iOriginalTypeHandle = tOriginal.TypeHandle.Value.ToInt64(); int iPropertyIndex = 0; //Indice interno della proprietà string sOrigFullTypeName = tOriginal.FullName; //la classe deve essere pubblica if (tOriginal.IsNotPublic) { throw new TypeFactoryException("La classe '{0}' deve essere definita PUBLIC.", sOrigFullTypeName); } //Definisce TypeBuilder TypeBuilder typeBuild = dapx.PxModuleBuilder.DefineType(string.Concat(STR_BDO_SUFFIX, sOrigFullTypeName), TypeAttributes.Public | TypeAttributes.Sealed, tOriginal); ConstructorBuilder cbDefault = typeBuild.DefineDefaultConstructor(MethodAttributes.Public); //Se non necessario schema va ad aggiunta entry if (!bCreateSchema) { goto ADD_TYPE_ENTRY; } //Carica i Metodi Custom per GET e SET MethodInfo myGetCustom = tOriginal.GetMethod("GetProperty", BindingFlags.Instance | BindingFlags.Public); MethodInfo mySetCustom = tOriginal.GetMethod("SetProperty", BindingFlags.Instance | BindingFlags.Public); //Carica elenco proprieta' arrPropInfo = tOriginal.GetProperties(BindingFlags.Instance | BindingFlags.Public); //Ordina le proprieta' per come sono state definite Array.Sort <PropertyInfo>(arrPropInfo, delegate(PropertyInfo p1, PropertyInfo p2) { return(p1.MetadataToken.CompareTo(p2.MetadataToken)); }); //Loop su proprietà for (int i = 0; i < arrPropInfo.Length; i++) { PropertyInfo prop = arrPropInfo[i]; //Cattura Get e Set Correnti MethodInfo getMethod = prop.GetGetMethod(); MethodInfo setMethod = prop.GetSetMethod(); MethodBuilder newGetMethod = null; MethodBuilder newSetMethod = null; //Crea i nuovi metodi //GET if ((getMethod != null) && (getMethod.IsAbstract)) { //Creo un nuovo metodo GET newGetMethod = typeBuild.DefineMethod(getMethod.Name, MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, prop.PropertyType, null); //Creo codice IL ILGenerator ilGen = newGetMethod.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4, iPropertyIndex); ilGen.Emit(OpCodes.Call, myGetCustom); ilGen.Emit(OpCodes.Unbox_Any, prop.PropertyType); ilGen.Emit(OpCodes.Ret); } //SET if ((setMethod != null) && (setMethod.IsAbstract)) { //Creo un nuovo metodo SET newSetMethod = typeBuild.DefineMethod(setMethod.Name, MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new Type[] { prop.PropertyType }); //Creo codice IL ILGenerator ilGen = newSetMethod.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4, iPropertyIndex); ilGen.Emit(OpCodes.Ldarg_1); if (prop.PropertyType.IsValueType) { ilGen.Emit(OpCodes.Box, prop.PropertyType); } ilGen.Emit(OpCodes.Call, mySetCustom); ilGen.Emit(OpCodes.Ret); } //Se è stato generato almeno un metodo if (newGetMethod != null || newSetMethod != null) { PropertyBuilder propBuild = typeBuild.DefineProperty(prop.Name, PropertyAttributes.None, prop.PropertyType, new Type[] { prop.PropertyType }); //Se c'è GET imposta nuovo metodo if (newGetMethod != null) { typeBuild.DefineMethodOverride(newGetMethod, getMethod); } //Se c'è SET imposta nuovo metodo if (newSetMethod != null) { typeBuild.DefineMethodOverride(newSetMethod, setMethod); } //Incrementa contatore di proprietà mappata iPropertyIndex++; } else { //Si tratta di proprieta' non mappata, quindi la imposta a null arrPropInfo[i] = null; } } ADD_TYPE_ENTRY: //Crea oggetto appoggio cont tipo + delegato costruttore ProxyEntryDao oTypeEntry = new ProxyEntryDao(); oTypeEntry.ProxyType = typeBuild.CreateType(); oTypeEntry.Create = createFastConstructor(oTypeEntry.ProxyType, dapx.PxModuleBuilder); //Crea schema dei soli oggetti singoli if (bCreateSchema) { oTypeEntry.ClassSchema = readClassSchemaWithSQL(tOriginal, iOriginalTypeHandle, arrPropInfo); } //Aggiunge a lista su proxy outProxy.TypeDaoEntries.Add(iOriginalTypeHandle, oTypeEntry); } catch (Exception ex) { throw new SchemaReaderException("Errore dutante la scansione dell'assembly {0}. {1}", outProxy.SrcAss.FullName, ex.Message); } } }