Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3262,7 +3262,7 @@ public void ExecuteBeforeCommit(string callerName)
{
inBeforeCommit = true;
if (beforeCommitObj != null)
ClassLoader.ExecuteVoidRef(beforeCommitObj, "execute", new Object[] { callerName });
ClassLoader.ExecuteVoidRef(beforeCommitObj, "execute", new Object[] { callerName }, "Before Commit");
inBeforeCommit = false;
}
}
Expand All @@ -3273,7 +3273,7 @@ public void ExecuteAfterCommit(string callerName)
{
inAfterCommit = true;
if (afterCommitObj != null)
ClassLoader.ExecuteVoidRef(afterCommitObj, "execute", new Object[] { callerName });
ClassLoader.ExecuteVoidRef(afterCommitObj, "execute", new Object[] { callerName },"After Commit");
inAfterCommit = false;
}
}
Expand All @@ -3284,7 +3284,7 @@ public void ExecuteBeforeRollback(string callerName)
{
inBeforeRollback = true;
if (beforeRollbackObj != null)
ClassLoader.ExecuteVoidRef(beforeRollbackObj, "execute", new Object[] { callerName });
ClassLoader.ExecuteVoidRef(beforeRollbackObj, "execute", new Object[] { callerName }, "Before Rollback");
inBeforeRollback = false;
}
}
Expand All @@ -3295,7 +3295,7 @@ public void ExecuteAfterRollback(string callerName)
{
inAfterRollback = true;
if (afterRollbackObj != null)
ClassLoader.ExecuteVoidRef(afterRollbackObj, "execute", new Object[] { callerName });
ClassLoader.ExecuteVoidRef(afterRollbackObj, "execute", new Object[] { callerName }, "After Rollback");
inAfterRollback = false;
}
}
Expand All @@ -3305,7 +3305,7 @@ public bool ExecuteBeforeConnect(IGxDataStore datastore)
if (beforeConnectObj != null)
{
GXLogging.Debug(Logger, "ExecuteBeforeConnect");
ClassLoader.ExecuteVoidRef(beforeConnectObj, "execute", new Object[] { datastore });
ClassLoader.ExecuteVoidRef(beforeConnectObj, "execute", new Object[] { datastore }, "Before Connect");
return true;
}
else
Expand All @@ -3319,7 +3319,7 @@ public bool ExecuteAfterConnect(String datastoreName)
if (afterConnectObj != null)
{
GXLogging.Debug(Logger, "ExecuteAfterConnect");
ClassLoader.ExecuteVoidRef(afterConnectObj, "execute", new Object[] { datastoreName });
ClassLoader.ExecuteVoidRef(afterConnectObj, "execute", new Object[] { datastoreName }, "After Connect");
return true;
}
else
Expand Down
117 changes: 114 additions & 3 deletions dotnet/src/dotnetframework/GxClasses/Helpers/GXMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace GeneXus.Metadata
#endif
using GeneXus.Application;
using System.Collections.Concurrent;
using System.Text;

public class ClassLoader
{
Expand Down Expand Up @@ -233,8 +234,11 @@ internal static string ConstructorArgsString(Object[] constructorArgs)
}
return argsConstr;
}

static public void ExecuteVoidRef(object o, string mthd, Object[] args)
{
ExecuteVoidRef(o, mthd, args, null);
}
internal static void ExecuteVoidRef(object o, string mthd, Object[] args, string propertyName)
{
try
{
Expand Down Expand Up @@ -269,15 +273,18 @@ static public void ExecuteVoidRef(object o, string mthd, Object[] args)
pm[0] = ((pi.Attributes & ParameterAttributes.In) != ParameterAttributes.None);
pm[1] = ((pi.Attributes & ParameterAttributes.Out) != ParameterAttributes.None);
pm[2] = pi.ParameterType.IsByRef;
pms[i] = pm;
if (i < pms.Length)
{
pms[i] = pm;
}
}
try
{
o.GetType().InvokeMember(mthd, BindingFlags.InvokeMethod, null, o, args, pms, null, null);

}catch(MissingMethodException)
{
throw new GxClassLoaderException("Method " + mi.DeclaringType.FullName + "." + mi.Name + " for " + args.Length + " parameters ("+ String.Join(",", args) + ") not found");
throw new GxClassLoaderException(BuildParameterMismatchErrorMessage(mi.DeclaringType.FullName, pis, args, propertyName));
}
}
else
Expand All @@ -294,6 +301,110 @@ static public void ExecuteVoidRef(object o, string mthd, Object[] args)
throw GxClassLoaderException.ProcessException(e);
}
}
static string BuildParameterMismatchErrorMessage(string objectName, ParameterInfo[] methodParameters, object[] runtimeMethodParameters, string propertyName)
{
string parmInfo = GetParameterTypesString(methodParameters);
string runtimeParms = GetParameterValuesString(runtimeMethodParameters);
StringBuilder errorMessage = new StringBuilder();

errorMessage.Append($"Program {objectName} ");
if (!string.IsNullOrEmpty(propertyName))
{
errorMessage.Append($"referenced in {propertyName} property ");
}
errorMessage.Append($"does not have the expected parameter definition.");
if (methodParameters.Length == 0)
{
errorMessage.Append($"It does not have any parameters.");
}
else
{
errorMessage.Append($"Program parameter definition: {parmInfo}.");
}

if (runtimeMethodParameters.Length == 0)
{
errorMessage.Append($"No parameter values were provided at runtime. ");
}
else if (runtimeMethodParameters.Length == 1)
{
errorMessage.Append($"Parameter value provided at runtime: {runtimeParms}. ");
}
else
{
errorMessage.Append($"Parameter values provided at runtime: {runtimeParms}. ");
}
errorMessage.Append($"Please check the parm rule of the {objectName}.");

return errorMessage.ToString();
}

static string GetParameterValuesString(object[] runtimeMethodParameters)
{
StringBuilder sb = new StringBuilder();
sb.Append('(');

for (int i = 0; i < runtimeMethodParameters.Length; i++)
{
object parmValue = runtimeMethodParameters[i];
string parmStringValue = (parmValue is string) ? $"\"{parmValue}\"" : parmValue.ToString();
sb.Append(parmStringValue);
if (i < runtimeMethodParameters.Length - 1)
{
sb.Append(", ");
}
}
sb.Append(')');
return sb.ToString();
}

static string GetParameterTypesString(ParameterInfo[] parameters)
{
StringBuilder sb = new StringBuilder();
sb.Append('(');

for (int i = 0; i < parameters.Length; i++)
{
string parmTypeName = ParameterTypeName(parameters[i].ParameterType);
sb.Append(parmTypeName);
if (i < parameters.Length - 1)
{
sb.Append(", ");
}
}
sb.Append(')');
return sb.ToString();
}

static string ParameterTypeName(Type parameterType)
{
Type innerType = (parameterType.IsByRef && parameterType.GetElementType()!=null) ? parameterType.GetElementType() : parameterType;
if (IsNumericType(innerType))
return "Numeric";
return innerType.Name;
}

static bool IsNumericType(Type type)
{
if (type == typeof(byte) ||
type == typeof(sbyte) ||
type == typeof(short) ||
type == typeof(ushort) ||
type == typeof(int) ||
type == typeof(uint) ||
type == typeof(long) ||
type == typeof(ulong) ||
type == typeof(float) ||
type == typeof(double) ||
type == typeof(decimal))
{
return true;
}
else
{
return false;
}
}
static public void ExecuteRef(object o, string mthd, Object[] args)
{
GXLogging.Debug(log, "ExecuteRef '" + "class '" + o + "' mthd '" + mthd + "'");
Expand Down