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