/// <summary> /// An attribute builder method /// </summary> /// <param name="attr"></param> /// <returns></returns> public static CustomAttributeBuilder GetCustomAttributeBuilder(SWCommandAttribute attr) { string commandText = attr.m_commandText; object returnIfNull = attr.m_returnIfNull; if (returnIfNull == null) { returnIfNull = NullReturnValueToken; } Type[] arrParamTypes = new Type[] { typeof(SWCommandType), typeof(string), typeof(object), typeof(MissingSchemaAction) }; object[] arrParamValues = new object[] { attr.m_commandType, commandText, returnIfNull, attr.m_missingSchemaAction }; ConstructorInfo ctor = typeof(SWCommandAttribute).GetConstructor(arrParamTypes); return(new CustomAttributeBuilder(ctor, arrParamValues)); }
/// <summary> /// Adds attributes and an implementation to a method of the created class. /// </summary> /// <param name="method">MethodInfo object.</param> /// <param name="tb">Type builder object.</param> private static void AddMethodImplementation(MethodInfo method, TypeBuilder tb) { // get method return type Type RetType = method.ReturnType; // get method paramete information ParameterInfo [] prms = method.GetParameters(); int paramCount = prms.Length; // get method parameter types and names Type [] paramTypes = new Type [paramCount]; string[] paramNames = new string[paramCount]; ParameterAttributes[] paramAttrs = new ParameterAttributes[paramCount]; for (int i = 0; i < paramCount; ++i) { paramTypes[i] = prms[i].ParameterType; paramNames[i] = prms[i].Name; paramAttrs[i] = prms[i].Attributes; } // define method body MethodBuilder methodBody = tb.DefineMethod(method.Name, MethodAttributes.Public | MethodAttributes.Virtual, method.ReturnType, paramTypes); // define method attribute if exists SWCommandAttribute CommandMethodAttr = (SWCommandAttribute)Attribute.GetCustomAttribute(method, typeof(SWCommandAttribute)); if (CommandMethodAttr != null) { methodBody.SetCustomAttribute(SWCommandAttribute.GetCustomAttributeBuilder(CommandMethodAttr)); } // define method parameters with their attributes for (int i = 0; i < paramCount; ++i) { ParameterBuilder param = methodBody.DefineParameter(i + 1, paramAttrs[i], paramNames[i]); SWParameterAttribute[] ParameterAttr = (SWParameterAttribute[])prms[i].GetCustomAttributes(typeof(SWParameterAttribute), false); if (ParameterAttr.Length > 0) { param.SetCustomAttribute(SWParameterAttribute.GetCustomAttributeBuilder(ParameterAttr[0])); } } // generate method body GenerateMethodBody(methodBody.GetILGenerator(), RetType, prms); }
/// <summary> /// An attribute builder method /// </summary> /// <param name="attr"></param> /// <returns></returns> public static CustomAttributeBuilder GetCustomAttributeBuilder(SWCommandAttribute attr) { string commandText = attr.m_commandText; object returnIfNull = attr.m_returnIfNull; if(returnIfNull == null) returnIfNull = NullReturnValueToken; Type[] arrParamTypes = new Type[] {typeof(SWCommandType), typeof(string), typeof(object), typeof(MissingSchemaAction)}; object[] arrParamValues = new object[] {attr.m_commandType, commandText, returnIfNull, attr.m_missingSchemaAction}; ConstructorInfo ctor = typeof(SWCommandAttribute).GetConstructor(arrParamTypes); return new CustomAttributeBuilder(ctor, arrParamValues); }
/// <summary> /// Executes Sql command and returns execution result. /// Command text, type and parameters are taken from method using reflection. /// Command parameter values are taken from method parameter values. /// </summary> /// <param name="connection">Connection property.</param> /// <param name="transaction">Transaction property.</param> /// <param name="method"><see cref="MethodInfo"/> type object from which the command object is built.</param> /// <param name="values">Array of values for the command parameters.</param> /// <param name="autoCloseConnection">Determines if the connection must be closed after the command execution.</param> /// <returns></returns> public static object ExecuteMethodAndGetResult(DbConnection connection, DbTransaction transaction, MethodInfo method, object[] values, bool autoCloseConnection) { if (method == null) { // this is done because this method can be called explicitly from code. method = (MethodInfo)(new StackTrace().GetFrame(1).GetMethod()); } // create command object DatabaseHelper db = new DatabaseHelper(); DbCommand command = db.Command; command.Connection = connection; command.Transaction = transaction; // define default command properties (command text, command type and missing schema action) string commandText = method.Name; SWCommandType swCommandType = SWCommandType.StoredProcedure; MissingSchemaAction missingSchemaAction = MissingSchemaAction.Add; // try to get command properties from calling method attribute SWCommandAttribute commandAttribute = (SWCommandAttribute)Attribute.GetCustomAttribute(method, typeof(SWCommandAttribute)); if (commandAttribute != null) { if (commandAttribute.CommandText.Length > 0) { commandText = commandAttribute.CommandText; } swCommandType = commandAttribute.CommandType; missingSchemaAction = commandAttribute.MissingSchemaAction; } // set command text command.CommandText = commandText; // set command type switch (swCommandType) { case SWCommandType.InsertUpdate: command.CommandType = CommandType.Text; break; case SWCommandType.StoredProcedure: command.CommandType = CommandType.StoredProcedure; break; case SWCommandType.Text: command.CommandType = CommandType.Text; break; default: command.CommandType = CommandType.Text; break; } // define command parameters. // In this step command text can be changed. int[] indexes = new int[values.Length]; GenerateCommandParameters(command, method, values, indexes, swCommandType); // execute command object result = null; result = ExecuteCommand(command, method.ReturnType, autoCloseConnection, missingSchemaAction); // return command parameter values for (int i = 0; i < values.Length; ++i) { int sqlParamIndex = indexes[i]; if (sqlParamIndex >= 0) { values[i] = command.Parameters[i].Value; } } // adjust null result if (result == null || result == System.DBNull.Value) { if (commandAttribute != null) { result = commandAttribute.ReturnIfNull; if (method.ReturnType == typeof(DateTime)) { result = new DateTime((int)commandAttribute.ReturnIfNull); } } } return(result); }