A dynamic method data. For generating by DynamicClassFactory.
Esempio n. 1
0
        /// <summary>	Adds a method dynamically. </summary>
        ///
        /// <param name="typeBuilder">			The type builder. </param>
        /// <param name="methodName">			Name of the method. </param>
        /// <param name="dynamicMethodData">	Information describing the dynamic method. </param>
        private void AddMethodDynamically(TypeBuilder typeBuilder, string methodName, DynamicMethodData dynamicMethodData)
        {
            Type[]        paramTypes    = (dynamicMethodData.Params == null || dynamicMethodData.Params.Length == 0) ? null : dynamicMethodData.Params.Select(t => t.Type).ToArray();
            MethodBuilder methodBuilder = typeBuilder.DefineMethod(methodName,
                                                                   MethodAttributes.Public |
                                                                   MethodAttributes.Static,
                                                                   dynamicMethodData.ReturnType,
                                                                   paramTypes);

            ILGenerator ILout = methodBuilder.GetILGenerator();

            int numParams = dynamicMethodData.Params == null ? 0 : dynamicMethodData.Params.Length;

            for (int i = 0; i < numParams; i++)
            {
                var paramAttribute = ParameterAttributes.None;
                if (dynamicMethodData.Params[i].isIn)
                {
                    paramAttribute |= ParameterAttributes.In;
                }
                if (dynamicMethodData.Params[i].isOut)
                {
                    paramAttribute |= ParameterAttributes.Out;
                }

                methodBuilder.DefineParameter(i + 1, paramAttribute, dynamicMethodData.Params[i].Name.Replace("@", string.Empty));
            }

            for (byte x = 0; x < numParams; x++)
            {
                ILout.Emit(OpCodes.Ldarg_S, x);
            }

            string methodAction = string.Empty;

            if (numParams > 1)
            {
                for (int y = 0; y < (numParams - 1); y++)
                {
                    switch (methodAction)
                    {
                    case "A": ILout.Emit(OpCodes.Add);
                        break;

                    case "M": ILout.Emit(OpCodes.Mul);
                        break;

                    default: ILout.Emit(OpCodes.Add);
                        break;
                    }
                }
            }
            ILout.Emit(OpCodes.Ret);

            AddActionAttribute(methodBuilder);
            AddFunctionAttribute(methodBuilder, methodName, dynamicMethodData);
        }
Esempio n. 2
0
        /// <summary>	Adds a function attribute. </summary>
        ///
        /// <param name="methodBuilder">		The method builder. </param>
        /// <param name="methodName">			Name of the method. </param>
        /// <param name="dynamicMethodData">	Information describing the dynamic method. </param>
        private void AddFunctionAttribute(MethodBuilder methodBuilder, string methodName, DynamicMethodData dynamicMethodData)
        {
            Type attrType = typeof(System.Data.Entity.DbFunctionAttribute);
            var  attr     = new CustomAttributeBuilder(attrType.GetConstructor(
                                                           new[] { typeof(string), typeof(string) }),
                                                       new object[] { dynamicMethodData.Schema, methodName });

            methodBuilder.SetCustomAttribute(attr);
        }
        /// <summary>	Adds the actions to model. </summary>
        ///
        /// <param name="modelBuilder">		  	The builder that defines the model for the context being
        /// 									created. </param>
        /// <param name="schema">			  	The schema. </param>
        /// <param name="dynamicClassFactory">	The dynamic class factory. </param>
        ///
        /// <returns>	A Type. </returns>
        private static void AddActionsToModel(
            DbModelBuilder modelBuilder,
            DatabaseSchema schema,
            DynamicClassFactory dynamicClassFactory)
        {
            foreach (var function in schema.Functions)
            {
                try
                {
                    if (function.ReturnType != null)
                    {
                        var dynamicMethodData = new DynamicMethodData();
                        dynamicMethodData.FunctionType = FunctionType.ModelDefinedFunction;
                        dynamicMethodData.ReturnType = typeof(Int32);
                        dynamicMethodData.Schema = function.SchemaOwner;
                        if (function.Arguments.Count > 0)
                        {
                            dynamicMethodData.Params = new DynamicParameterData[function.Arguments.Count];
                            for (int i = 0; i < function.Arguments.Count; i++)
                            {
                                dynamicMethodData.Params[i] = new DynamicParameterData()
                                {
                                    Name = function.Arguments[i].Name,
                                    Type = function.Arguments[i].DataType.GetNetType(),
                                    isIn = function.Arguments[i].In,
                                    isOut = function.Arguments[i].Out,
                                    Length = function.Arguments[i].Length
                                };
                            }
                        }
                        _dynamicActionMethods.Add(function.Name, dynamicMethodData);
                    }
                }
                catch (Exception exception)
                {
                    DynamicLogger.Instance.WriteLoggerLogError("AddActionsToModel", exception);
                }
            }

            foreach (var procedure in schema.StoredProcedures)
            {
                try
                {
                    var dynamicMethodData = new DynamicMethodData();
                    dynamicMethodData.FunctionType = FunctionType.ModelDefinedFunction;
                    dynamicMethodData.ReturnType = typeof(Int32);
                    dynamicMethodData.Schema = procedure.SchemaOwner;
                    if (procedure.Arguments.Count > 0)
                    {
                        dynamicMethodData.Params = new DynamicParameterData[procedure.Arguments.Count];
                        for (int i = 0; i < procedure.Arguments.Count; i++)
                        {
                            dynamicMethodData.Params[i] = new DynamicParameterData()
                            {
                                Name = procedure.Arguments[i].Name,
                                Type = procedure.Arguments[i].DataType.GetNetType(),
                                isIn = procedure.Arguments[i].In,
                                isOut = procedure.Arguments[i].Out,
                                Length = procedure.Arguments[i].Length
                            };
                        }
                    }
                    _dynamicActionMethods.Add(procedure.Name, dynamicMethodData);
                }
                catch (Exception exception)
                {
                    DynamicLogger.Instance.WriteLoggerLogError("AddActionsToModel", exception);
                }
            }

            try
            {
                _dynamicActions = CreateTypeAction(dynamicClassFactory, "DbActions", _dynamicActionMethods);
                // https://www.nuget.org/packages/EntityFramework.Functions
                modelBuilder.AddFunctions(_dynamicActions, false);
            }
            catch (Exception exception)
            {
                DynamicLogger.Instance.WriteLoggerLogError("AddActionsToModel", exception);
            }
        }