typeA
is not a created type so it is not allowed to do that (typeA.GetConstructors()
will also fail). Build type first:
var typeA = moduleBuilder.DefineType("classA");
typeA.DefineDefaultConstructor(MethodAttributes.Public);
// typeA.GetConstructors() will fail
var type = typeA.CreateType();
type.GetConstructors(); // typeA.GetConstructors() works too
typeof(Func<>).MakeGenericType(type).GetConstructors();
But to create a Func<T>
from a constructor you actually don't need the func's constructor, you should be able to use any of methods described here or here.
P.S.
Useful tool to see how compiler handle thigs is sharplab.io. You can see both decompilation to C# and IL.
This decompilation should represent your scenario.
UPD
I would suggest just to create a helper class (in code) which will do what is needed (i.e. return MessageParser
with func returning invocation of default ctor) and then use it to call via emit:
public class Helper
{
public static MessageParser<T> GetDefaultMessageParser<T>() where T : new() => new MessageParser<T>(() => new T());
}
And generation:
var assembleBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Dynamic"), AssemblyBuilderAccess.RunAndCollect);
var moduleBuilder = assembleBuilder.DefineDynamicModule("Dynamic.dll");
var typeA = moduleBuilder.DefineType("classA");
var defaultConstructorBuilder = typeA.DefineTypeInitializer(); // define static ctor
var mpType = typeof(MessageParser<>).MakeGenericType(typeA);
var parserFieldBuilder = typeA.DefineField("Parser", mpType, FieldAttributes.Static | FieldAttributes.Private);
var methodInfo = typeof(Helper)
.GetMethod(nameof(Helper.GetDefaultMessageParser))
.MakeGenericMethod(typeA);
var ctorGenerator = defaultConstructorBuilder.GetILGenerator();
ctorGenerator.Emit(OpCodes.Call, methodInfo);
ctorGenerator.Emit(OpCodes.Stsfld, parserFieldBuilder);
ctorGenerator.Emit(OpCodes.Ret);
var type = typeA.CreateType();
var instance = Activator.CreateInstance(type);
var value = type.GetField("Parser", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(new object[] { });
Console.WriteLine(value?.ToString()); // prints MessageParser`1[classA]
But in general I would recommend switching to source generators (here my sandbox one, for example) which will allow you to generate your class during compilation with, I would argue, much less effort and less error prone.