[Screen Action] Screen Action component - parameters?

[Screen Action] Screen Action component - parameters?

  
Forge Component
(4)
Published on 2 Nov by Matheus Medeiros
4 votes
Published on 2 Nov by Matheus Medeiros

I've done reflection on action parameters before - this is the method I put together (I wanted to be able to use some things in OutSystems as a data source in addition to some external programs so everything could go through the same extension)

I don't know if this or something similar would work on screen actions:

public static string OutSystemsRuntimePlatformAssemblyName = "OutSystems.HubEdition.RuntimePlatform";

private static Assembly GetOutSystemsAssembly()
{
    Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
    Assembly result = assemblies.ToList<Assembly>().First<Assembly>(a => a.GetName().Name.Equals(
        OutSystemsRuntimePlatformAssemblyName, StringComparison.InvariantCultureIgnoreCase));
    return result;
}

private static Assembly GetESpaceAssembly(string eSpace)
{
    Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
    try
    {
        Assembly result = assemblies.ToList<Assembly>().First<Assembly>(a => a.GetName().Name.Equals(
            eSpace, StringComparison.InvariantCultureIgnoreCase));
        return result;
    }
    catch (Exception e)
    {
        List<string> assemblyNames = new List<string>();
        assemblies.ToList<Assembly>().ForEach(assembly => assemblyNames.Add(assembly.GetName().Name));
        throw new InvalidOperationException(e.Message + Environment.NewLine +
            "Could not find " + eSpace + " in " +
            string.Join(", ", assemblyNames.ToArray<string>()));
    }
}

private static object NewContext(Assembly outSystemsAssembly)
{
    Type contextType = outSystemsAssembly.GetType("OutSystems.HubEdition.RuntimePlatform.HeContext");
    object contextInstance = Activator.CreateInstance(contextType);
    return contextInstance;
}

public static object NewContext()
{
    return NewContext(GetOutSystemsAssembly());
}

/// <param name="eSpace"></param>
/// <param name="actionName"></param>
/// <param name="parameters">For OutSystems, the parameters <i>must start with a NewContext()</i> -
/// we could add it ourselves, but <b>out</b> parameters get put back on the passed-in array and
/// that would be a bit of a pain.</param>
/// <returns></returns>
public static object InvokeAction(string eSpace, string actionName, ref object[] parameters)
{
    Assembly outSystemsAssembly = GetOutSystemsAssembly();
    if (outSystemsAssembly == null)
        throw new ArgumentException("Could not find OutSystems runtime assembly.");
    Assembly eSpaceAssembly = GetESpaceAssembly(eSpace);
    if (eSpaceAssembly == null)
        throw new ArgumentException(string.Format("No assembly could be found for eSpace.", eSpace));
    Type actionsType = eSpaceAssembly.GetType(string.Format("ss{0}.Actions", eSpace));
    if (actionsType == null)
    {
        Type[] types = eSpaceAssembly.GetTypes();
        StringBuilder typesBuilder = new StringBuilder();
        foreach (Type type in types)
            typesBuilder.AppendLine(type.Name);
        throw new ArgumentException(string.Format("Invalid eSpace or incompatibility: {0}\nListed types: {1}",
            eSpace, typesBuilder.ToString()));
    }
    try
    {
        object result = actionsType.InvokeMember(string.Format("Action{0}", actionName), BindingFlags.InvokeMethod |
            BindingFlags.Static | BindingFlags.Public, null, null, parameters);
        return result;
    }
    catch (Exception e)
    {
        if (e.InnerException != null)
            throw new Exception(e.Message + Environment.NewLine + e.InnerException.Message +
                Environment.NewLine + e.InnerException.StackTrace, e);
        else
            throw new Exception(e.Message, e);
    }
}