/// <summary> /// Initializes a new instance of the <see cref="ConstructorBuilder"/> class /// with the specified parameters. /// </summary> /// <param name="typeBuilder">Associated <see cref="TypeBuilderHelper"/>.</param> /// <param name="constructorBuilder">A <see cref="ConstructorBuilder"/></param> public ConstructorBuilderHelper(TypeBuilderHelper typeBuilder, ConstructorBuilder constructorBuilder) : base(typeBuilder) { if (constructorBuilder == null) throw new ArgumentNullException("constructorBuilder"); _constructorBuilder = constructorBuilder; _constructorBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute); }
/// <summary> /// Initializes a new instance of the <see cref="MethodBuilderHelper"/> class /// with the specified parameters. /// </summary> /// <param name="typeBuilder">Associated <see cref="TypeBuilderHelper"/>.</param> /// <param name="methodBuilder">A <see cref="MethodBuilder"/></param> public MethodBuilderHelper(TypeBuilderHelper typeBuilder, MethodBuilder methodBuilder) : base(typeBuilder) { if (methodBuilder == null) throw new ArgumentNullException("methodBuilder"); _methodBuilder = methodBuilder; methodBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute); }
/// <summary> /// Initializes a new instance of the <see cref="MethodBuilderHelper"/> class /// with the specified parameters. /// </summary> /// <param name="typeBuilder">Associated <see cref="TypeBuilderHelper"/>.</param> protected MethodBuilderBase(TypeBuilderHelper typeBuilder) { if (typeBuilder == null) { throw new ArgumentNullException("typeBuilder"); } _type = typeBuilder; }
/// <summary> /// Initializes a new instance of the <see cref="ConstructorBuilder"/> class /// with the specified parameters. /// </summary> /// <param name="typeBuilder">Associated <see cref="TypeBuilderHelper"/>.</param> /// <param name="constructorBuilder">A <see cref="ConstructorBuilder"/></param> public ConstructorBuilderHelper(TypeBuilderHelper typeBuilder, ConstructorBuilder constructorBuilder) : base(typeBuilder) { if (constructorBuilder == null) { throw new ArgumentNullException("constructorBuilder"); } _constructorBuilder = constructorBuilder; _constructorBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute); }
public Type Build(Type sourceType, AssemblyBuilderHelper assemblyBuilder) { if (sourceType == null) throw new ArgumentNullException("sourceType"); if (assemblyBuilder == null) throw new ArgumentNullException("assemblyBuilder"); // Check InternalsVisibleToAttributes of the source type's assembly. // Even if the sourceType is public, it may have internal fields and props. // _friendlyAssembly = false; // Usually, there is no such attribute in the source assembly. // Therefore we do not cache the result. // object[] attributes = sourceType.Assembly.GetCustomAttributes(typeof(InternalsVisibleToAttribute), true); foreach (InternalsVisibleToAttribute visibleToAttribute in attributes) { AssemblyName an = new AssemblyName(visibleToAttribute.AssemblyName); if (AssemblyName.ReferenceMatchesDefinition(assemblyBuilder.AssemblyName, an)) { _friendlyAssembly = true; break; } } if (!sourceType.IsVisible && !_friendlyAssembly) throw new TypeBuilderException(string.Format("Can not build type accessor for non-public type '{0}'.", sourceType.FullName)); string typeName = GetTypeAccessorClassName(_type); _typeBuilder = assemblyBuilder.DefineType(typeName, _accessorType); _typeBuilder.DefaultConstructor.Emitter .ldarg_0 .call (TypeHelper.GetDefaultConstructor(_accessorType)) ; BuildCreateInstanceMethods(); BuildTypeProperties(); BuildMembers(); BuildObjectFactory(); _typeBuilder.DefaultConstructor.Emitter .ret() ; Type result = _typeBuilder.Create(); foreach (TypeBuilderHelper tb in _nestedTypes) tb.Create(); return result; }
/// <summary> /// Initializes a new instance of the <see cref="MethodBuilderHelper"/> class /// with the specified parameters. /// </summary> /// <param name="typeBuilder">Associated <see cref="TypeBuilderHelper"/>.</param> /// <param name="methodBuilder">A <see cref="MethodBuilder"/></param> /// <param name="dummy">A dummpy parameter to alter the signature</param> internal MethodBuilderHelper(TypeBuilderHelper typeBuilder, MethodBuilder methodBuilder, bool dummy) : base(typeBuilder) { if (methodBuilder == null) throw new ArgumentNullException("methodBuilder"); _methodBuilder = methodBuilder; // There is a bug related to generic parameters, so we add this attribute later. // // _methodBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute); }
/// <summary> /// Initializes a new instance of the <see cref="MethodBuilderHelper"/> class /// with the specified parameters. /// </summary> /// <param name="typeBuilder">Associated <see cref="TypeBuilderHelper"/>.</param> /// <param name="methodBuilder">A <see cref="MethodBuilder"/></param> public MethodBuilderHelper(TypeBuilderHelper typeBuilder, MethodBuilder methodBuilder) : base(typeBuilder) { if (methodBuilder == null) { throw new ArgumentNullException("methodBuilder"); } _methodBuilder = methodBuilder; methodBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute); }
public Type Build(AssemblyBuilderHelper assemblyBuilder) { _typeBuilder = assemblyBuilder.DefineType(GetTypeName(), typeof(DuckType), _interfaceType); if (!BuildMembers(_interfaceType)) return null; foreach (Type t in _interfaceType.GetInterfaces()) if (!BuildMembers(t)) return null; return _typeBuilder.Create(); }
/// <summary> /// Initializes a new instance of the <see cref="MethodBuilderHelper"/> class /// with the specified parameters. /// </summary> /// <param name="typeBuilder">Associated <see cref="TypeBuilderHelper"/>.</param> /// <param name="methodBuilder">A <see cref="MethodBuilder"/></param> /// <param name="dummy">A dummpy parameter to alter the signature</param> internal MethodBuilderHelper(TypeBuilderHelper typeBuilder, MethodBuilder methodBuilder, bool dummy) : base(typeBuilder) { if (methodBuilder == null) { throw new ArgumentNullException("methodBuilder"); } _methodBuilder = methodBuilder; // There is a bug related to generic parameters, so we add this attribute later. // // _methodBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute); }
private void CreateReadObjectFunction(Type type, TypeBuilderHelper helper) { }
private void CreateProperty(TypeBuilderHelper typeBuilderHelper) { var dbObjectContainerField = typeBuilderHelper.DefineField("dbObjectContainer", typeof (DbObjectContainer), FieldAttributes.Private); var objectContainerProperty = typeBuilderHelper.TypeBuilder.DefineProperty("DbObjectContainer", PropertyAttributes.HasDefault, typeof (DbObjectContainer), new[] { typeof(DbObjectContainer) }); var attributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; var objectContainerGetMethod = typeBuilderHelper.DefineMethod("get_DbObjectContainer", attributes, typeof(DbObjectContainer), Type.EmptyTypes); var objectContainerGetMethodEmit = objectContainerGetMethod.Emitter; objectContainerGetMethodEmit .ldarg_0 .ldfld(dbObjectContainerField) .ret(); var objectContainerSetMethod = typeBuilderHelper.DefineMethod("set_DbObjectContainer", attributes, null, typeof(DbObjectContainer)); var objectContainerSetMethodEmit = objectContainerSetMethod.Emitter; objectContainerSetMethodEmit .ldarg_0 .ldarg_1 .stfld(dbObjectContainerField) .ret(); objectContainerProperty.SetGetMethod(objectContainerGetMethod); objectContainerProperty.SetSetMethod(objectContainerSetMethod); }
/// <summary> /// This method will create implementations for the getter/setter of property in a domain interface /// </summary> /// <param name="mDataInferface"></param> /// <param name="generatedTypeBuilder"></param> /// <param name="entityBase"></param> /// <param name="logicField"></param> private void MapProperties(Type mDataInferface, TypeBuilderHelper generatedTypeBuilder, Type entityBase, FieldBuilder logicField) { foreach (var p in mDataInferface.GetProperties()) { var propType = p.PropertyType; propType = ReplacePropertyTypeIfNeede(propType); //create the property definition var property = generatedTypeBuilder.TypeBuilder.DefineProperty(p.Name, PropertyAttributes.None, propType, null); //generate getter/setter logic CreatePropertyGetMethod(generatedTypeBuilder, p, property, p.GetGetMethod(), logicField); CreatePropertySetMethod(generatedTypeBuilder, p, property, p.GetSetMethod(), logicField); } }
private void BuildIsNull( MemberInfo mi, TypeBuilderHelper nestedType, Type memberType) { Type methodType = mi.DeclaringType; MethodInfo getMethod = null; Boolean isNullable = TypeHelper.IsNullable(memberType); Boolean isValueType = (!isNullable && memberType.IsValueType); if (!isValueType && mi is PropertyInfo) { getMethod = ((PropertyInfo)mi).GetGetMethod(); if (getMethod == null) { if (_type != _originalType) { getMethod = _type.GetMethod("get_" + mi.Name); methodType = _type; } if (getMethod == null) return; } } MethodInfo methodInfo = _memberAccessor.GetMethod("IsNull"); if (methodInfo == null) return; MethodBuilderHelper method = nestedType.DefineMethod(methodInfo); EmitHelper emit = method.Emitter; if (isValueType) { emit .ldc_i4_0 .end() ; } else { LocalBuilder locObj = null; if (isNullable) locObj = method.Emitter.DeclareLocal(memberType); emit .ldarg_1 .castType (methodType) .end(); if (mi is FieldInfo) emit.ldfld ((FieldInfo)mi); else emit.callvirt(getMethod); if (isNullable) { emit .stloc(locObj) .ldloca(locObj) .call(memberType, "get_HasValue") .ldc_i4_0 .ceq .end(); } else { emit .ldnull .ceq .end(); } } emit .ret() ; }
/// <summary> /// Initializes a new instance of the <see cref="MethodBuilderHelper"/> class /// with the specified parameters. /// </summary> /// <param name="typeBuilder">Associated <see cref="TypeBuilderHelper"/>.</param> /// <param name="methodBuilder">A <see cref="MethodBuilder"/></param> /// <param name="genericArguments">Generic arguments of the method.</param> /// <param name="returnType">The return type of the method.</param> /// <param name="parameterTypes">The types of the parameters of the method.</param> internal MethodBuilderHelper( TypeBuilderHelper typeBuilder, MethodBuilder methodBuilder, Type[] genericArguments, Type returnType, Type[] parameterTypes ) : base(typeBuilder) { if (methodBuilder == null) { throw new ArgumentNullException("methodBuilder"); } if (genericArguments == null) { throw new ArgumentNullException("genericArguments"); } _methodBuilder = methodBuilder; string[] genArgNames = Array.ConvertAll <Type, string>(genericArguments, delegate(Type t) { return(t.Name); }); GenericTypeParameterBuilder[] genParams = methodBuilder.DefineGenericParameters(genArgNames); // Copy parameter constraints. // List <Type> interfaceConstraints = null; for (int i = 0; i < genParams.Length; i++) { genParams[i].SetGenericParameterAttributes(genericArguments[i].GenericParameterAttributes); foreach (Type constraint in genericArguments[i].GetGenericParameterConstraints()) { if (constraint.IsClass) { genParams[i].SetBaseTypeConstraint(constraint); } else { if (interfaceConstraints == null) { interfaceConstraints = new List <Type>(); } interfaceConstraints.Add(constraint); } } if (interfaceConstraints != null && interfaceConstraints.Count != 0) { genParams[i].SetInterfaceConstraints(interfaceConstraints.ToArray()); interfaceConstraints.Clear(); } } // When a method contains a generic parameter we need to replace all // generic types from methodInfoDeclaration with local ones. // for (int i = 0; i < parameterTypes.Length; i++) { parameterTypes[i] = TypeHelper.TranslateGenericParameters(parameterTypes[i], genParams); } methodBuilder.SetParameters(parameterTypes); methodBuilder.SetReturnType(TypeHelper.TranslateGenericParameters(returnType, genParams)); // Once all generic stuff is done is it is safe to call SetCustomAttribute // methodBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute); }
private void BuildGetter(MemberInfo mi, TypeBuilderHelper nestedType) { Type methodType = mi.DeclaringType; MethodInfo getMethod = null; if (mi is PropertyInfo) { getMethod = ((PropertyInfo)mi).GetGetMethod(); if (getMethod == null) { if (_type != _originalType) { getMethod = _type.GetMethod("get_" + mi.Name); methodType = _type; } if (getMethod == null || !IsMethodAccessible(getMethod)) return; } } MethodBuilderHelper method = nestedType.DefineMethod( _memberAccessor.GetMethod("GetValue", typeof(object))); EmitHelper emit = method.Emitter; emit .ldarg_1 .castType (methodType) .end(); if (mi is FieldInfo) { FieldInfo fi = (FieldInfo)mi; emit .ldfld (fi) .boxIfValueType (fi.FieldType) ; } else { PropertyInfo pi = (PropertyInfo)mi; emit .callvirt (getMethod) .boxIfValueType (pi.PropertyType) ; } emit .ret() ; nestedType.DefineMethod(_memberAccessor.GetProperty("HasGetter").GetGetMethod()).Emitter .ldc_i4_1 .ret() ; }
/// <summary> /// Creates / gets the correct field for the generated class which represents the logicbase class for a given /// MData interface. /// </summary> /// <param name="generatedFields"></param> /// <param name="typeBuilder"></param> /// <param name="interfaceToImplement"></param> /// <param name="isMethodData"></param> /// <param name="logicClassType"></param> /// <returns></returns> private static FieldBuilder CreateLogicBaseField(Dictionary<Type, FieldBuilder> generatedFields, TypeBuilderHelper typeBuilder, Type interfaceToImplement, bool isMethodData, ref Type logicClassType) { //not all interfaces implemented by domainType necesarly have the MData attribute //they could also have the MDataMethod attribute meaning that they will be implemented //by the same logic class as the MDataMethod attribute's parameter //if the interface is a MDataMethod interface, assign it to the linked logicClass if (isMethodData) { var linkedInterfaceType = interfaceToImplement.GetAttributes<MDataMethodAttribute>().First().GetLinkedInterfaceType(); logicClassType = generatedFields[linkedInterfaceType].FieldType; return generatedFields[linkedInterfaceType]; } return typeBuilder.DefineField(GetFieldFullName(logicClassType), logicClassType,FieldAttributes.FamORAssem); }
private static ConstructorBuilderHelper BuildNestedTypeConstructor(TypeBuilderHelper nestedType) { Type[] parameters = { typeof(TypeAccessor), typeof(MemberInfo) }; ConstructorBuilderHelper ctorBuilder = nestedType.DefinePublicConstructor(parameters); ctorBuilder.Emitter .ldarg_0 .ldarg_1 .ldarg_2 .call (TypeHelper.GetConstructor(typeof(MemberAccessor), parameters)) .ret() ; return ctorBuilder; }
private void BuildTypedSetterForNullable( MemberInfo mi, TypeBuilderHelper nestedType, Type memberType) { Type methodType = mi.DeclaringType; MethodInfo setMethod = null; if (mi is PropertyInfo) { setMethod = ((PropertyInfo)mi).GetSetMethod(); if (setMethod == null) { if (_type != _originalType) { setMethod = _type.GetMethod("set_" + mi.Name); methodType = _type; } if (setMethod == null || !IsMethodAccessible(setMethod)) return; } } Type setterType = (memberType.IsEnum ? Enum.GetUnderlyingType(memberType) : memberType); MethodInfo methodInfo = _memberAccessor.GetMethod("Set" + setterType.Name, typeof(object), setterType); if (methodInfo == null) return; MethodBuilderHelper method = nestedType.DefineMethod(methodInfo); EmitHelper emit = method.Emitter; emit .ldarg_1 .castType (methodType) .ldarg_2 .newobj (typeof(Nullable<>).MakeGenericType(memberType), memberType) .end(); if (mi is FieldInfo) emit.stfld ((FieldInfo)mi); else emit.callvirt(setMethod); emit .ret() ; }
private void BuildTypedGetterForNullable( MemberInfo mi, TypeBuilderHelper nestedType, Type memberType) { Type methodType = mi.DeclaringType; MethodInfo getMethod = null; if (mi is PropertyInfo) { getMethod = ((PropertyInfo)mi).GetGetMethod(); if (getMethod == null) { if (_type != _originalType) { getMethod = _type.GetMethod("get_" + mi.Name); methodType = _type; } if (getMethod == null || !IsMethodAccessible(getMethod)) return; } } Type setterType = (memberType.IsEnum ? Enum.GetUnderlyingType(memberType) : memberType); MethodInfo methodInfo = _memberAccessor.GetMethod("Get" + setterType.Name, typeof(object)); if (methodInfo == null) return; MethodBuilderHelper method = nestedType.DefineMethod(methodInfo); Type nullableType = typeof(Nullable<>).MakeGenericType(memberType); LocalBuilder locObj = method.Emitter.DeclareLocal(nullableType); EmitHelper emit = method.Emitter; emit .ldarg_1 .castType (methodType) .end(); if (mi is FieldInfo) emit.ldfld ((FieldInfo)mi); else emit.callvirt(getMethod); emit .stloc(locObj) .ldloca(locObj) .call(nullableType, "get_Value") .ret() ; }
private void BuildCloneValueMethod( MemberInfo mi, TypeBuilderHelper nestedType, Type memberType ) { Type methodType = mi.DeclaringType; MethodInfo getMethod = null; MethodInfo setMethod = null; if (mi is PropertyInfo) { getMethod = ((PropertyInfo)mi).GetGetMethod(); if (getMethod == null) { if (_type != _originalType) { getMethod = _type.GetMethod("get_" + mi.Name); methodType = _type; } if (getMethod == null || !IsMethodAccessible(getMethod)) return; } setMethod = ((PropertyInfo)mi).GetSetMethod(); if (setMethod == null) { if (_type != _originalType) { setMethod = _type.GetMethod("set_" + mi.Name); methodType = _type; } if (setMethod == null || !IsMethodAccessible(setMethod)) return; } } MethodBuilderHelper method = nestedType.DefineMethod( _memberAccessor.GetMethod("CloneValue", typeof(object), typeof(object))); EmitHelper emit = method.Emitter; emit .ldarg_2 .castType (methodType) .ldarg_1 .castType (methodType) .end(); if (mi is FieldInfo) emit.ldfld ((FieldInfo)mi); else emit.callvirt(getMethod); if (typeof(string) != memberType && TypeHelper.IsSameOrParent(typeof(ICloneable), memberType)) { if (memberType.IsValueType) emit .box (memberType) .callvirt (typeof(ICloneable), "Clone") .unbox_any (memberType) ; else { Label valueIsNull = emit.DefineLabel(); emit .dup .brfalse_s (valueIsNull) .callvirt (typeof(ICloneable), "Clone") .castclass (memberType) .MarkLabel (valueIsNull) ; } } if (mi is FieldInfo) emit.stfld ((FieldInfo)mi); else emit.callvirt(setMethod); emit .ret() ; }
private void BuildTypedSetter( MemberInfo mi, TypeBuilderHelper nestedType, Type memberType, string typedPropertyName) { Type methodType = mi.DeclaringType; MethodInfo setMethod = null; if (mi is PropertyInfo) { setMethod = ((PropertyInfo)mi).GetSetMethod(); if (setMethod == null) { if (_type != _originalType) { setMethod = _type.GetMethod("set_" + mi.Name); methodType = _type; } if (setMethod == null || !IsMethodAccessible(setMethod)) return; } } MethodInfo methodInfo = _memberAccessor.GetMethod("Set" + typedPropertyName, typeof(object), memberType); if (methodInfo == null) return; MethodBuilderHelper method = nestedType.DefineMethod(methodInfo); EmitHelper emit = method.Emitter; emit .ldarg_1 .castType (methodType) .ldarg_2 .end(); if (mi is FieldInfo) emit.stfld ((FieldInfo)mi); else emit.callvirt(setMethod); emit .ret() ; }
private void CreateInsertFunction(Type type, TypeBuilderHelper helper) { throw new NotImplementedException(); }
private void CreateUpdateFunction(Type type, TypeBuilderHelper typeBuilderHelper) { var classMetadata = ClassMetaDataManager.Instace.GetClassMetaData(type); var properties = classMetadata.Properties; var mappingTable = classMetadata.MappingTable; var methodEmit = typeBuilderHelper.DefineMethod(typeof (IDbFunctionHelper).GetMethod("Update")).Emitter; var resultLocal = methodEmit.DeclareLocal(typeof (int)); var commandLocal = methodEmit.DeclareLocal(typeof (DbCommand)); var commandParameters = methodEmit.DeclareLocal(typeof (DbParameterCollection)); var queryBuilder = new StringBuilder("UPDATE " + mappingTable + " SET "); var objectNotDirtyLabel = methodEmit.DefineLabel(); foreach (var mappingInfo in properties.Values) { if (mappingInfo.MappingField != "Id") { queryBuilder.Append(mappingInfo.MappingField + "=@" + mappingInfo.MappingField + ", "); } } var tmpString = queryBuilder.ToString(0, queryBuilder.Length - 2); queryBuilder.Length = 0; queryBuilder.Append(tmpString); queryBuilder.Append(" WHERE Id = @Id"); methodEmit .ldarg_1 .call(typeof(IDbObject).GetMethod("get_IsDirty")) .brfalse(objectNotDirtyLabel) .ldc_i4_0 .stloc(resultLocal) .ldarg_2 .call(typeof(DbConnection).GetMethod("CreateCommand")) .stloc(commandLocal) .ldloc(commandLocal) .ldstr(queryBuilder.ToString()) .call(typeof(DbCommand).GetMethod("set_CommandText")) .ldloc(commandLocal) .call(typeof(DbCommand).GetMethod("get_Parameters")) .stloc(commandParameters); foreach (var mappingInfo in properties.Values) { var propertyInfo = mappingInfo.PropertyInfo; var mappingField = mappingInfo.MappingField; var propertyType = propertyInfo.PropertyType; if (propertyType.IsPrimitive || propertyType == typeof(string) || propertyType == typeof(DateTime) || propertyType == typeof(decimal)) { methodEmit .ldloc(commandParameters) .ldstr("@" + mappingField) //Param 1 for MySqlParameter constructor .ldarg_1 .call(propertyInfo.GetGetMethod()) //Param 2 for MySqlParameter constructor .newobj(typeof (MySqlParameter), typeof (string), typeof (object)) // Param for Add of DbParameterCollection .call(typeof (DbParameterCollection).GetMethod("Add", new[] {typeof (object)})) ; } else //Property that need to be convert to byte array before set { var propetyValueLocal = methodEmit.DeclareLocal(propertyType); var dbSerializerHelperLocal = methodEmit.DeclareLocal(typeof (DbSerializerHelper)); var memoryStreamLocal = methodEmit.DeclareLocal(typeof (MemoryStream)); var propertyByteArray = methodEmit.DeclareLocal(typeof (byte[])); methodEmit .ldarg_1 .call(propertyInfo.GetGetMethod()) .stloc(propetyValueLocal) .newobj(typeof(MemoryStream), Type.EmptyTypes) .stloc(memoryStreamLocal); methodEmit.BeginExceptionBlock(); methodEmit .ldloc(memoryStreamLocal) .newobj(typeof(BinaryWriter), typeof(Stream)) .newobj(typeof(DbSerializerHelper), typeof(BinaryWriter)) .stloc(dbSerializerHelperLocal) .ldloc(dbSerializerHelperLocal) .ldarg_1 .call(propertyInfo.GetGetMethod()) .call(typeof(DbSerializerHelper).GetMethod("Write", new[] {propertyType})) .ldloc(memoryStreamLocal) .call(typeof(MemoryStream).GetMethod("ToArray")) .stloc(propertyByteArray) .ldloc(commandParameters) .ldstr("@" + mappingField) .ldloc(propertyByteArray) .newobj(typeof(MySqlParameter), typeof(string), typeof(object)) // Param for Add of DbParameterCollection .call(typeof(DbParameterCollection).GetMethod("Add", new[] { typeof(object) })) .BeginFinallyBlock() .ldloc(memoryStreamLocal) .call(typeof(IDisposable).GetMethod("Dispose")) .EndExceptionBlock() ; } } methodEmit .ldloc(commandLocal) .call(typeof(DbCommand).GetMethod("ExecuteNonQuery")) .stloc(resultLocal) .ldarg_1 .ldc_bool(false) .call(typeof(IDbObject).GetMethod("set_IsDirty")) .MarkLabel(objectNotDirtyLabel); //Update relation var relations = classMetadata.RelationProperties; LocalBuilder queryExecutorLocal = null; if (relations.Count > 0) { queryExecutorLocal = methodEmit.DeclareLocal(typeof (IQueryExecutor)); var dbObjectContainerField = typeBuilderHelper.TypeBuilder.GetField("dbObjectContainer"); methodEmit .ldfld(dbObjectContainerField) .call(typeof (DbObjectContainer).GetMethod("get_QueryExecutor")) .stloc(queryExecutorLocal); } foreach (var relationInfo in relations.Values) { var propertyInfo = relationInfo.PropertyInfo; var propertyType = propertyInfo.PropertyType; var elementType = propertyType.IsGenericType ? propertyType.GetGenericArguments()[0] : propertyType; var listPersistentDbObjectLocal = methodEmit.DeclareLocal(typeof(IList<long>)); var listCurrentType = typeof (List<>).MakeGenericType(elementType); var addElementMethod = typeof (ICollection<>).MakeGenericType(elementType).GetMethod("Add"); var countElementMethod = typeof (ICollection<>).MakeGenericType(elementType).GetMethod("Count"); var listConstructorMethod = listCurrentType.GetConstructor(new[] {typeof (IEnumerable<>).MakeGenericType(elementType)}); var listCurrentDbObjectLocal = methodEmit.DeclareLocal(listCurrentType); var mappingColumn = relationInfo.PartnerKey; var relationCommandLocal = methodEmit.DeclareLocal(typeof (DbCommand)); var readerLocal = methodEmit.DeclareLocal(typeof (DbDataReader)); var relationTimeInfoLocal = methodEmit.DeclareLocal(typeof (TimeRelationInfo)); var commandText = "SELECT " + mappingColumn + " FROM " + mappingTable + " WHERE Id = @Id"; methodEmit .ldarg_2 .call(typeof (DbConnection).GetMethod("CreateCommand")) .stloc(relationCommandLocal) .ldloc(relationCommandLocal) .ldstr(commandText) .call(typeof (DbCommand).GetMethod("set_CommandText")) .ldloc(relationCommandLocal) .call(typeof(DbCommand).GetMethod("ExecuteReader")) .stloc(readerLocal) .ldstr(mappingColumn) .ldloc(readerLocal) .call(typeof(DbSerializerHelper).GetMethod("ReadRelationTimeInfo")) .stloc(relationTimeInfoLocal) .ldloc(relationTimeInfoLocal) .ldfld(typeof(TimeRelationInfo).GetField("idList")) .stloc(listPersistentDbObjectLocal) ; if (relationInfo.RelationKind == RelationInfo.RELATION_1_1) { methodEmit .newobj(listCurrentType, Type.EmptyTypes) .stloc(listCurrentDbObjectLocal) .ldloc(listCurrentDbObjectLocal) .ldarg_1 .call(propertyInfo.GetGetMethod()) .call(addElementMethod) ; } else { methodEmit .ldarg_1 .call(propertyInfo.GetGetMethod()) .newobj(listConstructorMethod) .stloc(listCurrentDbObjectLocal) ; } var lenLocal = methodEmit.DeclareLocal(typeof (int)); var iLocal = methodEmit.DeclareLocal(typeof (int)); var beginForLabel = methodEmit.DefineLabel(); var beginForBodyLabel = methodEmit.DefineLabel(); var itemLocal = methodEmit.DeclareLocal(elementType); var itemIdLocal = methodEmit.DeclareLocal(typeof (long)); var itemNullLabel = methodEmit.DefineLabel(); var getCurrentObjectElementMethod = listCurrentType.GetMethod("get_Item", new[] {typeof (int)}); var listPersistentContainCurrentElementLabel = methodEmit.DefineLabel(); var listPersistentNotContainCurrentElementLabel = methodEmit.DefineLabel(); methodEmit .ldloc(listCurrentDbObjectLocal) .call(countElementMethod) .stloc(lenLocal) .ldc_i4_0 .stloc(iLocal) .br(beginForLabel) .MarkLabel(beginForBodyLabel) .ldloc(listCurrentDbObjectLocal) .ldloc(iLocal) .call(getCurrentObjectElementMethod) .stloc(itemLocal) .ldloc(itemLocal) .brfalse(itemNullLabel) .ldloc(itemLocal) .call(typeof(IDbObject).GetMethod("get_Id")) .stloc(itemIdLocal) .ldloc(listPersistentDbObjectLocal) .ldloc(itemIdLocal) .call(typeof(ICollection<long>).GetMethod("Contain")) .brtrue(listPersistentContainCurrentElementLabel) .ldloc(queryExecutorLocal) .ldloc(itemLocal) .ldnull .call(typeof(IQueryExecutor).GetMethod("Insert", new[] { typeof(IDbObject), typeof(IsolationLevel?), typeof(long), typeof(string) })) .br(listPersistentNotContainCurrentElementLabel) .MarkLabel(listPersistentContainCurrentElementLabel) .MarkLabel(listPersistentNotContainCurrentElementLabel) .MarkLabel(itemNullLabel) .ldloc(iLocal) .ldc_i4_1 .add .stloc(iLocal) .MarkLabel(beginForLabel) .ldloc(iLocal) .ldloc(lenLocal) .blt(beginForBodyLabel) ; } }
/// <summary> /// Creates the body of a property getter /// </summary> /// <param name="generatedTypeBuilder"></param> /// <param name="p"></param> /// <param name="property"></param> /// <param name="getDecl"></param> /// <param name="logicField"></param> private void CreatePropertyGetMethod(TypeBuilderHelper generatedTypeBuilder, PropertyInfo p, PropertyBuilder property, MethodInfo getDecl, FieldInfo logicField) { //set setter name and return type var setterName = getDecl == null ? "get_" + p.Name : getDecl.Name; var returnType = getDecl == null ? p.PropertyType : getDecl.ReturnType; //determine security attributes var methodAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual; //create setter method var getBuilder = generatedTypeBuilder.DefineMethod(setterName, methodAttributes, returnType, null); //emit IL opcode getBuilder .Emitter .nop .ldarg_0 .ldfld(logicField) .ldstr(p.Name) //this.LogicBase<[logicField.FieldType]>.GetProperty([methodName]) .callvirt(Reflect<LogicBase>.GetMethod(x => x.GetProperty<object>(string.Empty)).MakeGenericMethod(p.PropertyType)) .ret(); //apply the created method to the getter property.SetGetMethod(getBuilder); }
/// <summary> /// Initializes a new instance of the <see cref="MethodBuilderHelper"/> class /// with the specified parameters. /// </summary> /// <param name="typeBuilder">Associated <see cref="TypeBuilderHelper"/>.</param> /// <param name="methodBuilder">A <see cref="MethodBuilder"/></param> /// <param name="genericArguments">Generic arguments of the method.</param> /// <param name="returnType">The return type of the method.</param> /// <param name="parameterTypes">The types of the parameters of the method.</param> internal MethodBuilderHelper( TypeBuilderHelper typeBuilder, MethodBuilder methodBuilder, Type[] genericArguments, Type returnType, Type[] parameterTypes ) : base(typeBuilder) { if (methodBuilder == null) throw new ArgumentNullException("methodBuilder"); if (genericArguments == null) throw new ArgumentNullException("genericArguments"); _methodBuilder = methodBuilder; var genArgNames = genericArguments.Select(t => t.Name).ToArray(); var genParams = methodBuilder.DefineGenericParameters(genArgNames); // Copy parameter constraints. // List<Type> interfaceConstraints = null; for (var i = 0; i < genParams.Length; i++) { genParams[i].SetGenericParameterAttributes(genericArguments[i].GenericParameterAttributes); foreach (var constraint in genericArguments[i].GetGenericParameterConstraints()) { if (constraint.IsClass) genParams[i].SetBaseTypeConstraint(constraint); else { if (interfaceConstraints == null) interfaceConstraints = new List<Type>(); interfaceConstraints.Add(constraint); } } if (interfaceConstraints != null && interfaceConstraints.Count != 0) { genParams[i].SetInterfaceConstraints(interfaceConstraints.ToArray()); interfaceConstraints.Clear(); } } // When a method contains a generic parameter we need to replace all // generic types from methodInfoDeclaration with local ones. // for (var i = 0; i < parameterTypes.Length; i++) parameterTypes[i] = TypeHelper.TranslateGenericParameters(parameterTypes[i], genParams); methodBuilder.SetParameters(parameterTypes); methodBuilder.SetReturnType(TypeHelper.TranslateGenericParameters(returnType, genParams)); // Once all generic stuff is done is it is safe to call SetCustomAttribute // methodBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute); }
/// <summary> /// Creates the body of a property setter /// </summary> /// <param name="generatedTypeBuilder"></param> /// <param name="p"></param> /// <param name="property"></param> /// <param name="setDecl"></param> /// <param name="logicField"></param> private void CreatePropertySetMethod(TypeBuilderHelper generatedTypeBuilder, PropertyInfo p, PropertyBuilder property, MethodInfo setDecl, FieldInfo logicField) { //set getter name and parameter types var name = setDecl == null ? "set_" + p.Name : setDecl.Name; var parameterTypes = setDecl == null ? new[] { p.PropertyType } : setDecl.GetParameters().Select(x => x.ParameterType).ToArray(); //set attributes on setter var methodAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual; //build setter method var setBuilder = generatedTypeBuilder.DefineMethod(name, methodAttributes, null, parameterTypes); //spit out IL setBuilder .Emitter .ldarg_0 .ldfld(logicField) .ldstr(p.Name) .ldarg_1 .callvirt(Reflect<LogicBase>.GetMethod(x=> x.SetProperty(string.Empty, string.Empty)).MakeGenericMethod(p.PropertyType)) .nop .ret(); //apply setter method to the property property.SetSetMethod(setBuilder); }
/// <summary> /// Initializes a new instance of the <see cref="MethodBuilderHelper"/> class /// with the specified parameters. /// </summary> /// <param name="typeBuilder">Associated <see cref="TypeBuilderHelper"/>.</param> protected MethodBuilderBase(TypeBuilderHelper typeBuilder) { if (typeBuilder == null) throw new ArgumentNullException("typeBuilder"); _type = typeBuilder; }
/// <summary> /// All interface methods are implemented in the generated class in here /// </summary> /// <param name="logicField"></param> /// <param name="logicClass"></param> /// <param name="mDataInferface"></param> /// <param name="type"></param> private void MapMethods(FieldInfo logicField, Type logicClass, Type mDataInferface, TypeBuilderHelper type) { //loop all methods of the interface definition foreach (var methodInfo in mDataInferface.GetMethods()) { //only implement Methods if (methodInfo.MemberType != MemberTypes.Method) continue; //get_ and set_ methods are special cases, implement them as properties if (methodInfo.Name.StartsWith("get_") || methodInfo.Name.StartsWith("set_")) continue; //get method parameters and generic arguments var methodParameters = methodInfo.GetParameters(); var methodGenericArguments = methodInfo.GetGenericArguments(); MethodBuilderHelper methodBuilder; //check if we got to define a generic method or not if (methodGenericArguments.Length > 0) { methodBuilder = type.DefineGenericMethod(methodInfo.Name, MethodAttributes.Virtual | MethodAttributes.Public, CallingConventions.Standard, methodGenericArguments, methodInfo.ReturnType, methodParameters.Select(x => x.ParameterType).ToArray()); } else { methodBuilder = type.DefineMethod(methodInfo.Name, MethodAttributes.Virtual | MethodAttributes.Public, methodInfo.ReturnType, methodParameters.Select(x => x.ParameterType).ToArray()); } //get hold of the method emitter var emit = methodBuilder.Emitter; if (methodParameters.Any()) emit.DeclareLocal(typeof (object[])); //load 'this' instance emit .ldarg(0) .ldfld(logicField); var logicMethod = GetLogicMethod(logicClass, methodInfo); //logicmethod == null so we have to call UnImplemented*MethodCall function if (logicMethod == null) { logicMethod = methodInfo.ReturnType == typeof (void) ? Reflect<LogicBase>.GetMethod(x=>x.UnImplementedNoReturnMethodCall(string.Empty)) : Reflect<LogicBase>.GetMethod(x => x.UnImplementedMethodCall<object>(string.Empty)).MakeGenericMethod(methodInfo.ReturnType); //we store the parameters in a new object[] so we can pass them to the UnImpl methods emit = emit .ldc_i4_(methodParameters.Count()) .newarr(typeof (object)); if (methodParameters.Any()) { emit = emit.stloc_0; for (var index = 0; index < methodParameters.Length; index++) { emit .ldloc_0 .ldc_i4_(index) .ldarg(index + 1); //box value type (int, etc) and generic parameter (e.g. 'T') if (methodParameters[index].ParameterType.IsValueType || methodParameters[index].ParameterType.IsGenericParameter) emit.box(methodParameters[index].ParameterType); //store the first stack element in the array defined in the upper stack emit = emit .stelem_ref; } //load method name emit = emit .ldstr(methodInfo.Name) .ldloc_0; } else emit.ldstr(methodInfo.Name); } else { //load all method parameters onto stack foreach (var parameterInfo in methodParameters) { emit.ldarg(parameterInfo); } } //call the logic class emit .callvirt(logicMethod) .ret(); } }
/// <summary> /// Creates a constructor for a generated class. The constructor will call Init on the Logic classes. /// </summary> /// <param name="fieldsToInit"></param> /// <param name="generatedTypeBuilder"></param> /// <param name="entityBase"></param> private void CreateConstructorLogic(IEnumerable<FieldBuilder> fieldsToInit, TypeBuilderHelper generatedTypeBuilder, Type entityBase) { //define public constructor var constructor = generatedTypeBuilder.DefinePublicConstructor().Emitter; //call base() constructor = constructor .ldarg_0 .call(entityBase.GetConstructor(new Type[] {})); //initialize all fields foreach (var fieldBuilder in fieldsToInit) { constructor .ldarg_0 .newobj(fieldBuilder.FieldType) .stfld(fieldBuilder) .ldarg_0 .ldfld(fieldBuilder) .ldarg_0 .callvirt(typeof (LogicBase<>).MakeGenericType(fieldBuilder.FieldType).GetMethod("set_CurrentInstance")); } //exit constructor constructor.ret(); }
private void BuildSetter(MemberInfo mi, TypeBuilderHelper nestedType) { Type methodType = mi.DeclaringType; MethodInfo setMethod = null; if (mi is PropertyInfo) { setMethod = ((PropertyInfo)mi).GetSetMethod(); if (setMethod == null) { if (_type != _originalType) { setMethod = _type.GetMethod("set_" + mi.Name); methodType = _type; } if (setMethod == null || !IsMethodAccessible(setMethod)) return; } } //else if (((FieldInfo)mi).IsLiteral) // return; MethodBuilderHelper method = nestedType.DefineMethod( _memberAccessor.GetMethod("SetValue", typeof(object), typeof(object))); EmitHelper emit = method.Emitter; emit .ldarg_1 .castType (methodType) .ldarg_2 .end(); if (mi is FieldInfo) { FieldInfo fi = (FieldInfo)mi; emit .CastFromObject (fi.FieldType) .stfld (fi) ; } else { PropertyInfo pi = (PropertyInfo)mi; emit .CastFromObject (pi.PropertyType) .callvirt (setMethod) ; } emit .ret() ; nestedType.DefineMethod(_memberAccessor.GetProperty("HasSetter").GetGetMethod()).Emitter .ldc_i4_1 .ret() ; }