private static MethodBuilder CreateMethodBuilder(TypeBuilder typeBuilder, string methodName, Type returnType, Type[] parameterTypes, DryvControllerGenerationContext context, DryvDynamicControllerOptions options) { var methodBuilder = typeBuilder.DefineMethod(methodName, MethodAttributes.Public, returnType, parameterTypes); ControllerAttributeGenerator.AddCustomAttributes(context, options.MapActionFilters, methodBuilder.SetCustomAttribute); return(methodBuilder); }
public Assembly CreateControllerAssembly(MethodCallExpression methodExpression, Type modelType) { var methodInfo = methodExpression.Method; var key = GetCacheKey(methodInfo); return(Cache.GetOrAdd(key, _ => { var assemblyIndex = ++assemblyCount; var typeNameBase = $"DryvDynamic{assemblyIndex}"; var baseType = typeof(Controller); var currentAssembly = Assembly.GetExecutingAssembly(); var assemblyName = new AssemblyName($"DryvDynamicAssembly{assemblyIndex}") { CodeBase = currentAssembly.CodeBase, }; var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndCollect); var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name); var typeBuilder = moduleBuilder.DefineType($"{NameSpace}.{typeNameBase}Controller", TypeAttributes.Class | TypeAttributes.Public, baseType); var context = new DryvControllerGenerationContext(typeBuilder, methodInfo); ControllerAttributeGenerator.AddCustomAttributes(context, this.options.Value.MapControllerFilters, typeBuilder.SetCustomAttribute); var parameters = FindParameters(methodExpression); var modelParameter = parameters.Find(p => p.Type == modelType); var lambda = Expression.Lambda(methodExpression, parameters); var delegateField = typeBuilder.DefineField("_delegate", lambda.Type, FieldAttributes.Private | FieldAttributes.Static); parameters.Remove(modelParameter); var innerFields = parameters.ToDictionary( p => p, p => typeBuilder.DefineField(p.Name, p.Type, FieldAttributes.Private)); ControllerCtorGenerator.GenerateConstructor(typeBuilder, baseType, innerFields.Values.ToList()); if (this.options.Value.HttpMethod == DryvDynamicControllerMethods.Post) { ControllerMethodGenerator.GenerateWrapperMethodPost(methodInfo, modelType, lambda, typeBuilder, delegateField, innerFields, context, this.options.Value); } else { ControllerMethodGenerator.GenerateWrapperMethodGet(methodInfo, modelType, methodExpression, lambda, typeBuilder, delegateField, innerFields, context, this.options.Value); } var type = typeBuilder.CreateType(); var field = type.GetField("_delegate", BindingFlags.Static | BindingFlags.NonPublic); Debug.Assert(field != null); field.SetValue(null, lambda.Compile()); //var generator = new Lokad.ILPack.AssemblyGenerator(); //generator.GenerateAssembly(assemblyBuilder, $"EMIT.dll"); //Process.Start(new ProcessStartInfo //{ // UseShellExecute = true, // WindowStyle = ProcessWindowStyle.Normal, // FileName = "dotnet", // Arguments = $"ildasm EMIT.dll -o EMIT.ildasm --force", //}).WaitForExit(); return assemblyBuilder; })); }