Example #1
0
        public void Register(ITypeHandler typeHandler)
        {
            if (!_typeHandlerMap.TryGetValue(typeHandler.PropertyType, out var fieldTypeHandlerMap))
            {
                fieldTypeHandlerMap = new Dictionary <Type, ITypeHandler>();
                _typeHandlerMap.Add(typeHandler.PropertyType, fieldTypeHandlerMap);
            }

            if (fieldTypeHandlerMap.ContainsKey(typeHandler.FieldType))
            {
                fieldTypeHandlerMap[typeHandler.FieldType] = typeHandler;
            }
            else
            {
                fieldTypeHandlerMap.Add(typeHandler.FieldType, typeHandler);
            }

            TypeHandlerCacheType.SetHandler(typeHandler);
            PropertyTypeHandlerCacheType.SetHandler(typeHandler);
        }
Example #2
0
        private void BuildMethod(Type interfaceType, TypeBuilder typeBuilder, MethodInfo methodInfo, FieldBuilder sqlMapperField, SmartSqlConfig smartSqlConfig, string scope)
        {
            var methodParams = methodInfo.GetParameters();
            var paramTypes   = methodParams.Select(m => m.ParameterType).ToArray();

            if (paramTypes.Any(p => p.IsGenericParameter))
            {
                _logger.LogError("SmartSql.DyRepository method parameters do not support generic parameters for the time being!");
                throw new SmartSqlException("SmartSql.DyRepository method parameters do not support generic parameters for the time being!");
            }
            var returnType = methodInfo.ReturnType;

            var implMethod = typeBuilder.DefineMethod(methodInfo.Name
                                                      , MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final
                                                      , returnType, paramTypes);

            var isTaskReturnType = CommonType.Task.IsAssignableFrom(returnType);

            if (methodInfo.IsGenericMethod)
            {
                var genericArgs       = methodInfo.GetGenericArguments();
                var gArgNames         = genericArgs.Select(gArg => gArg.Name).ToArray();
                var defineGenericArgs = implMethod.DefineGenericParameters(gArgNames);
                for (int i = 0; i < gArgNames.Length; i++)
                {
                    var genericArg       = genericArgs[i];
                    var defineGenericArg = defineGenericArgs[i];
                    defineGenericArg.SetGenericParameterAttributes(genericArg.GenericParameterAttributes);
                }
            }

            StatementAttribute statementAttr = PreStatement(interfaceType, scope, methodInfo, returnType, isTaskReturnType, smartSqlConfig);
            var  ilGen          = implMethod.GetILGenerator();
            bool onlyOneParam   = paramTypes.Length == 1;
            Type firstParamType = paramTypes.FirstOrDefault();

            ilGen.DeclareLocal(RequestContextType.AbstractType);

            if (onlyOneParam && RequestContextType.AbstractType.IsAssignableFrom(firstParamType))
            {
                throw new SmartSqlException($"DyRepository.Method ParameterType :{firstParamType.FullName} can not be RequestContext.");
                //ilGen.LoadArg(1);
                //ilGen.StoreLocalVar(0);
            }

            bool isOnlyOneClassParam = onlyOneParam && !IsSimpleParam(firstParamType);

            EmitNewRequestContext(ilGen, isOnlyOneClassParam, firstParamType);
            EmitSetCommandType(ilGen, statementAttr);
            EmitSetDataSourceChoice(ilGen, statementAttr);

            if (String.IsNullOrEmpty(statementAttr.Sql))
            {
                EmitSetScope(ilGen, statementAttr.Scope);
                EmitSetSqlId(ilGen, statementAttr);
            }
            else
            {
                EmitSetRealSql(ilGen, statementAttr);
            }
            if (isOnlyOneClassParam)
            {
                ilGen.LoadLocalVar(0);
                ilGen.LoadArg(1);
                ilGen.Callvirt(RequestContextType.Method.SetRequest);
            }
            else if (paramTypes.Length > 0)
            {
                ilGen.DeclareLocal(SqlParameterType.SqlParameterCollection);
                bool ignoreParameterCase = smartSqlConfig.Settings.IgnoreParameterCase;
                ilGen.Emit(ignoreParameterCase ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
                ilGen.New(SqlParameterType.Ctor.SqlParameterCollection);
                ilGen.StoreLocalVar(1);
                for (int i = 0; i < methodParams.Length; i++)
                {
                    int    argIndex     = i + 1;
                    var    reqParam     = methodParams[i];
                    string reqParamName = reqParam.Name;
                    var    paramAttr    = reqParam.GetCustomAttribute <ParamAttribute>();
                    if (paramAttr != null && !String.IsNullOrEmpty(paramAttr.Name))
                    {
                        reqParamName = paramAttr.Name;
                    }
                    ilGen.LoadLocalVar(1);
                    ilGen.LoadString(reqParamName);
                    ilGen.LoadArg(argIndex);

                    if (reqParam.ParameterType.IsValueType)
                    {
                        ilGen.Box(reqParam.ParameterType);
                    }
                    ilGen.LoadType(reqParam.ParameterType);
                    ilGen.New(SqlParameterType.Ctor.SqlParameter);
                    ilGen.Dup();
                    var getHandlerMethod = paramAttr?.FieldType != null?TypeHandlerCacheType.GetHandlerMethod(reqParam.ParameterType, paramAttr?.FieldType)
                                               : PropertyTypeHandlerCacheType.GetHandlerMethod(reqParam.ParameterType);

                    ilGen.Call(getHandlerMethod);
                    ilGen.Call(SqlParameterType.Method.SetTypeHandler);
                    ilGen.Call(SqlParameterType.Method.Add);
                }
                ilGen.LoadLocalVar(0);
                ilGen.LoadLocalVar(1);
                ilGen.Callvirt(RequestContextType.Method.SetRequest);
            }
            MethodInfo executeMethod = PreExecuteMethod(statementAttr, returnType, isTaskReturnType);

            ilGen.LoadArg(0);
            ilGen.FieldGet(sqlMapperField);
            ilGen.LoadLocalVar(0);
            ilGen.Call(executeMethod);
            if (returnType == CommonType.Void)
            {
                ilGen.Pop();
            }
            ilGen.Return();
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug($"RepositoryBuilder.BuildMethod:{methodInfo.Name}->Statement:[Scope:{statementAttr.Scope},Id:{statementAttr.Id},Execute:{statementAttr.Execute},Sql:{statementAttr.Sql},IsAsync:{isTaskReturnType}]");
            }
        }