コード例 #1
0
        public void Init()
        {
            var alias             = "NamedTypeHandlerCacheTest";
            var namedTypeHandlers = new Dictionary <string, ITypeHandler>
            {
                { "Json", new JsonTypeHandler() },
                { "Xml", new XmlTypeHandler() }
            };

            NamedTypeHandlerCache.Build(alias, namedTypeHandlers);
            var jsonHandlerField = NamedTypeHandlerCache.GetTypeHandlerField(alias, "Json");
            var jsonTypeHandler  = jsonHandlerField.GetValue(null);
        }
コード例 #2
0
        public void Build()
        {
            var alias = "NamedTypeHandlerCacheTest";

            JsonTypeHandler expectedJson      = new JsonTypeHandler();
            XmlTypeHandler  expectedXml       = new XmlTypeHandler();
            var             namedTypeHandlers = new Dictionary <string, ITypeHandler>
            {
                { "Json", expectedJson },
                { "Xml", expectedXml }
            };

            NamedTypeHandlerCache.Build(alias, namedTypeHandlers);
            var actualJson = NamedTypeHandlerCache.GetTypeHandlerField(alias, "Json").GetValue(null);

            Assert.Equal(expectedJson, actualJson);

            var actualXml = NamedTypeHandlerCache.GetTypeHandlerField(alias, "Xml").GetValue(null);

            Assert.Equal(expectedXml, actualXml);
        }
コード例 #3
0
        private void BuildMethod(Type interfaceType, TypeBuilder typeBuilder, MethodInfo methodInfo,
                                 FieldBuilder sqlMapperField, SmartSqlConfig smartSqlConfig, SqlMap sqlMap)
        {
            var       returnType       = methodInfo.ReturnType;
            var       isTaskReturnType = CommonType.Task.IsAssignableFrom(returnType);
            Statement statement        = PreStatement(interfaceType, sqlMap, methodInfo, returnType, isTaskReturnType,
                                                      out var executeBehavior);

            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 implMethod = typeBuilder.DefineMethod(methodInfo.Name
                                                      , MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot |
                                                      MethodAttributes.Virtual | MethodAttributes.Final
                                                      , returnType, paramTypes);

            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);
                }
            }

            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);
            EmitStatementAttr(ilGen, methodInfo);
            EmitSetTransaction(ilGen, methodInfo);
            EmitSetScope(ilGen, sqlMap.Scope);
            EmitSetSqlId(ilGen, statement);
            EmitSetCache(ilGen, methodInfo);

            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);

                    #region Ensure TypeHanlder

                    ilGen.Dup();
                    if (paramAttr != null && !String.IsNullOrEmpty(paramAttr.TypeHandler))
                    {
                        var typeHandlerField =
                            NamedTypeHandlerCache.GetTypeHandlerField(smartSqlConfig.Alias, paramAttr.TypeHandler);
                        if (typeHandlerField == null)
                        {
                            throw new SmartSqlException(
                                      $"Can not find NamedTypeHandler SmartSql.Alias:[{smartSqlConfig.Alias}],Name :[{paramAttr.TypeHandler}].");
                        }

                        ilGen.FieldGet(typeHandlerField);
                    }
                    else
                    {
                        var getHandlerMethod = PropertyTypeHandlerCacheType.GetHandlerMethod(reqParam.ParameterType);
                        ilGen.Call(getHandlerMethod);
                    }

                    ilGen.Call(SqlParameterType.Method.SetTypeHandler);
                    ilGen.Call(SqlParameterType.Method.Add);

                    #endregion
                }

                ilGen.LoadLocalVar(0);
                ilGen.LoadLocalVar(1);
                ilGen.Callvirt(RequestContextType.Method.SetRequest);
            }

            MethodInfo executeMethod = PreExecuteMethod(executeBehavior, returnType, isTaskReturnType);
            ilGen.LoadArg(0);
            ilGen.FieldGet(sqlMapperField);
            ilGen.LoadLocalVar(0);
            ilGen.Callvirt(executeMethod);
            if (returnType == CommonType.Void)
            {
                ilGen.Pop();
            }

            ilGen.Return();
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug(
                    $"RepositoryBuilder.BuildMethod:{methodInfo.Name}->Statement:[Scope:{sqlMap.Scope},Id:{statement.Id},Execute:{executeBehavior},IsAsync:{isTaskReturnType}]");
            }
        }