How to Invoke Method<T>(Func<Action<T>> action) with private type

public class ThirdParty
{
    private struct MsgType { }
    private static void AnotherFunc(MsgType msg)
    {
        // Inserted to demonstrate getting here
        Console.WriteLine($"HEY: {msg}");
    }
}

public class AnotherThirdParty
{
    public static void CallEvent<T>(Func<int, Action<T>> action, T arg)
    {
        // Inserted to demonstrate calling the func and then
        // the action
        action(12)(arg);
    }
}

public static void Main()
{
    var msgTypeType = 
        typeof(ThirdParty).GetNestedType("MsgType", BindingFlags.NonPublic);

    // This is the message type we're passing (presumably you'll do more with it)
    var ourMsgTypeArg = Activator.CreateInstance(msgTypeType);

    // Get the reference to the CallEvent method
    var callEventMethod =
        typeof(AnotherThirdParty).GetMethod("CallEvent", BindingFlags.Public | BindingFlags.Static)
        .MakeGenericMethod(msgTypeType);

    // Get the reference to the AnotherFunc method
    var anotherFunc =
        typeof(ThirdParty).GetMethod("AnotherFunc", BindingFlags.NonPublic | BindingFlags.Static);

    // Build the func to pass along to CallEvent
    var func = CreateFunc(msgTypeType, anotherFunc);

    // Call the CallEvent<MsgType> method.
    callEventMethod.Invoke(null, new object[] {
        func,
        ourMsgTypeArg
    });
}

private static Delegate CreateFunc(Type msgType, MethodInfo anotherFunc)
{
    // The func takes an int
    var intArg = Expression.Parameter(typeof(int));

    // The action takes a msgType
    var msgTypeArg = Expression.Parameter(msgType);

    // Represent the call out to "AnotherFunc"
    var call = Expression.Call(null, anotherFunc, msgTypeArg);

    // Build the action to just make the call to "AnotherFunc"
    var action = Expression.Lambda(call, msgTypeArg);

    // Build the func to just return the action
    var func = Expression.Lambda(action, intArg);

    // Compile the chain and send it out
    return func.Compile();
}

This code functions as you've requested and prints the following:

HEY: UserQuery+ThirdParty+MsgType

This seems to run:

    MethodInfo miCreateDelegate = typeof(MethodInfo).GetMethod("CreateDelegate", new[] { typeof(Type), typeof(Object) });
    var ActionType = typeof(Action<>).MakeGenericType(MsgType);
    var lambdabody = Expression.Convert(Expression.Call(Expression.Constant(AnotherFunc), miCreateDelegate, new[] { Expression.Constant(ActionType), Expression.Constant(null) }), ActionType);
    var intparm = Expression.Parameter(typeof(int));
    var lambda = Expression.Lambda(lambdabody, intparm);

    CallEvent.Invoke(null, new object[] {
        lambda.Compile(),
        msg
    });

A more complete answer is how did I generate this? I used LINQPad to compile a simpler, similar expression substituting string for MsgType into an Expression:

public static void afunc(string x) { }

Expression<Func<int, Action<string>>> lambda = (int x) => new Action<string>(afunc);

Then I used the LINQPad Dump() function to output the expression tree.

lambda.Dump();

Then some spelunking in MSDN Expression documentation gave me the right static methods to create the pieces. I already knew how to instantiate generic types from an extension method for LINQPad that creates anonymous types on the fly to extend Dump() to exclude fields from anonymous objects, and I knew how to create lambdas from an extension method that extends LINQ with a proper SQL-translatable Left and Right Join operation.