I have a method that currently creates a dynamic type at run time. The method is largely taken from this thread. The code works as is and create the type just fine. However, later in the code I need to use this type as a generic. This is where I'm a bit stuck. The part where the generic type is used is here:
mlContext.Model.CreatePredictionEngine<TSrc,TDst>(ITransformer, DataViewSchema)
where the TDst is known prior to compile time, but TSrc is not. TSrc in this is example is my dynamic type which is created in this method:
public static Type CreateDynamicType(IEnumerable<DynamicTypeProperty> properties)
{
    StringBuilder classCode = new StringBuilder();
    // Generate the class code
    classCode.AppendLine("using System;");
    classCode.AppendLine("namespace Dexih {");
    classCode.AppendLine("public class DynamicClass {");
    foreach (var property in properties)
    {
        classCode.AppendLine($"public {property.Type.Name} {property.Name} {{get; set; }}");
    }
    classCode.AppendLine("}");
    classCode.AppendLine("}");
    var syntaxTree = CSharpSyntaxTree.ParseText(classCode.ToString());
    var references = new MetadataReference[]
    {
        MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),
        MetadataReference.CreateFromFile(typeof(DictionaryBase).GetTypeInfo().Assembly.Location)
    };
    var compilation = CSharpCompilation.Create("DynamicClass" + Guid.NewGuid() + ".dll",
        syntaxTrees: new[] { syntaxTree },
        references: references,
        options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
    using (var ms = new MemoryStream())
    {
        var result = compilation.Emit(ms);
        if (!result.Success)
        {
            var failures = result.Diagnostics.Where(diagnostic =>
                diagnostic.IsWarningAsError ||
                diagnostic.Severity == DiagnosticSeverity.Error);
            var message = new StringBuilder();
            foreach (var diagnostic in failures)
            {
                message.AppendFormat("{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
            }
            throw new Exception($"Invalid property definition: {message}.");
        }
        else
        {
            ms.Seek(0, SeekOrigin.Begin);
            var assembly = Assembly.Load(ms.ToArray());
            var dynamicType = assembly.GetType("Dexih.DynamicClass");                  
            return dynamicType;
        }
    }
}
Can anyone describe how to modify the CreateDynamicType method so that it can return a generic type which can be used in the CreatePredictionEngine function?
EDIT (based on Kit's answer)
At the very bottom, I create an instance of the prediction engine by invoking the generic method. However, that simply returns a generic object type. I need to be able to then call engine.Predict(args) to be able to actually make a prediction using the engine (see docs here). I tried casting the return object to a PredictionEngine type, but that didn't seem to work. Do I have to create a new generic method for the Predict method too?
var dynamicType = DynamicType.CreateDynamicType(properties);
var inputSchema = SchemaDefinition.Create(dynamicType);
var outputSchema = SchemaDefinition.Create(typeof(ModelOutput));
var dataType = mlContext.Model.GetType();
var createEngineGeneric = dataType.GetMethods().First(method => method.Name == "CreatePredictionEngine" && method.IsGenericMethod);
var genericMethod = createEngineGeneric.MakeGenericMethod(dynamicType, typeof(ModelOutput));
object[] args = new object[]{ model , true, inputSchema, outputSchema };
var engine = genericMethod.Invoke(mlContext.Model, args);
 
    