public static object GetRouteValues(MethodBase method, object key, MethodMapping methodMapping, TypeMapping typeMapping) { object routeValues = new { modelType = typeMapping.ModelType.PartialName(), index = methodMapping.Index }; if (!method.IsConstructor) { routeValues = new { modelType = typeMapping.ModelType.PartialName(), index = methodMapping.Index, methodName = methodMapping.MethodName }; } if (!method.IsStatic && key != null) { routeValues = new { modelType = typeMapping.ModelType.PartialName(), index = methodMapping.Index, methodName = methodMapping.MethodName, key }; } return(routeValues); }
public static MethodInfo SelectMethod(MethodInfo sourceMethod, Type type, BindingFlags binding = BindingFlags.Public) { var key = new KeyValuePair <MethodInfo, Type>(sourceMethod, type); return(MethodMapping.GetOrAdd(key, k => MatchMethod(k.Key, k.Value, binding))); }
public override async Task <bool> Evaluate(RulesEngineService rulesEngine) { MethodMapping methodMapping = rulesEngine.MetaModel.GetMethod(ScriptEntityType.Action, MethodName.ToString()); var @class = methodMapping.Class; // Create the object instance object @object = rulesEngine.Instantiate(@class); // Manually inject the rules Engine context into the object instance @class.GetProperty(nameof(ScriptClass.Context)).SetValue(@object, rulesEngine.Context); // Generate the method meta-data var method = @class.GetMethod(methodMapping.Method.Name); List <object> methodParameters = new List <object>(); method.GetParameters().ToList().ForEach(reflectionParameter => { var parameter = Parameters[reflectionParameter.Name]; if (parameter == null) { throw new ApplicationException($"Missing {nameof(Parameter)} {reflectionParameter.Name}"); } methodParameters.Add(parameter.Value); }); // Invoke the method - possibly asynchronously bool status = await methodMapping.Method.InvokeAsync(@object, methodParameters.ToArray()); return(status); }
private IWithReturnRedirector <TSubject, TProxy, TProxyResult, TSubjectResult> SetMethod <TProxyResult, TProxyParam, TSubjectParam> (Expression <Func <TProxy, TProxyResult> > invocation, Func <TProxyParam, TSubjectParam> with = null) { MethodMapping mapping = GetMemberAccessInfo(invocation); Func <object[], object[]> transform; if (with != null) { transform = (arguments) => new object[] { with((TProxyParam)arguments[0]) }; } else { transform = (args) => args; } var returnRedirector = new ProxyReturnRedirector <TSubject, TProxy, TProxyResult, TSubjectResult>() { generator = this.generator, map = this.map, pendingMapping = mapping, accesor = this.accesor, setter = this.setter, methodCall = this.methodCall, ParametersTransformation = transform }; // That's about it. (leave a pending mapping) // Make a new Proxy ReturnRedirector with previous data. return(returnRedirector); }
public MethodDescriptor(MethodMapping mapping, ActionDescriptor actionDescriptor) : base(mapping.Name) { Method = mapping.Method; Index = mapping.Index; AttributeArray = Method.GetCustomAttributes(true).OfType <Attribute>().ToArray(); parameters.AddRange(Method.GetParameters().Select(info => new ReflectedParameterDescriptor(info, actionDescriptor))); }
private static void WriteMethod(StreamWriter writer, MethodMapping method, bool isStatic = false) { var removeId = isStatic ? ", id : null" : string.Empty; writer.Write("'{0}': {{ method:'POST', params : {{ methodName:'{1}' {2} ", ToCamelCase(method.MethodName), method.MethodName, removeId); //foreach (var parameter in method.Parameters) //{ // writer.Write(", {0}:'@{0}' ", parameter.Name); //} writer.WriteLine(" } }, "); }
/// <summary> /// Map methods to actions. /// </summary> /// <param name="info">Method to inspect.</param> /// <remarks>Goes through all custom action attributes to check which HTTP methods /// the action is valid for.</remarks> /// <exception cref="ActionMappingException">Mapping collision. Do not both suffix methods with a verb and use ValidFor attribute.</exception> private void MapMethod(MethodInfo info) { string verb; string methodName = info.Name; bool isFound = TryGetVerb(ref methodName, out verb); MethodMapping mapping; if (!_methods.TryGetValue(methodName.ToLower(), out mapping)) { mapping = new MethodMapping(); _methods.Add(methodName.ToLower(), mapping); } // specified a verb if (isFound) { _logger.Trace("Mapped " + _uri + "." + methodName.ToLower() + " to " + verb); mapping.IsMethodsSpecified = true; mapping.Add(verb, info); } // Check if method is valid only for a few verbs foreach (object customAttribute in info.GetCustomAttributes(false)) { var attr = customAttribute as ValidForAttribute; if (attr == null) { continue; } if (isFound) { throw new ActionMappingException( "Mapping collision. Do not both suffix methods with a verb and use ValidFor attribute."); } mapping.IsMethodsSpecified = true; foreach (string method in attr.Methods) { _logger.Trace("Mapped " + _uri + "." + methodName.ToLower() + " to " + method); mapping.Add(method, info); } } if (!mapping.IsMethodsSpecified) { _logger.Trace("Mapped " + _uri + "." + methodName.ToLower() + " to ALL verbs"); mapping.Add(verb, info); } }
public IWithGetOrSetRedirector <TSubject, TProxy, TSubjectResult, TProxyResult> Property <TProxyResult>(Expression <Func <TProxy, TProxyResult> > invocation) { MethodMapping mapping = GetMemberAccessInfo(invocation); var propertyRedirector = new PropertyRedirector <TSubject, TProxy, TSubjectResult, TProxyResult>() { generator = this.generator, map = this.map, setter = this.setter, accesor = this.accesor, pendingMapping = mapping }; return(propertyRedirector); }
public MethodCallExpressionResolve(ExpressionParameter parameter) : base(parameter) { var express = base.Expression as MethodCallExpression; var isLeft = parameter.IsLeft; string methodName = express.Method.Name; var isValidNativeMethod = MethodMapping.ContainsKey(methodName) && express.Method.DeclaringType.Namespace == ("System"); List <MethodCallExpressionArgs> appendArgs = null; if (MethodTimeMapping.ContainsKey(methodName)) { appendArgs = new List <MethodCallExpressionArgs>(); var dateType = MethodTimeMapping[methodName]; string paramterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex; appendArgs.Add(new MethodCallExpressionArgs() { IsMember = false, MemberName = paramterName, MemberValue = dateType }); this.Context.Parameters.Add(new SugarParameter(paramterName, dateType.ToString())); this.Context.ParameterIndex++; methodName = "DateAdd"; isValidNativeMethod = true; } else if (methodName == "get_Item") { string paramterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex; this.Context.Parameters.Add(new SugarParameter(paramterName, ExpressionTool.DynamicInvoke(express))); this.Context.Result.Append(string.Format(" {0} ", paramterName)); this.Context.ParameterIndex++; return; } else if (methodName == "NewGuid") { this.Context.Result.Append(this.Context.DbMehtods.GuidNew()); return; } if (!isValidNativeMethod && express.Method.DeclaringType.Namespace.IsIn("System.Linq", "System.Collections.Generic") && methodName == "Contains") { methodName = "ContainsArray"; isValidNativeMethod = true; } if (isValidNativeMethod) { NativeExtensionMethod(parameter, express, isLeft, MethodMapping[methodName], appendArgs); } else { SqlFuncMethod(parameter, express, isLeft); } }
public new static ConditionExpression Parse(Metamodel metaModel, string expressionText) { var groupedMatches = Syntax.Condition.Matches(expressionText)[0].Groups; // e.g - Func.GreaterThan:Int32:1,Logic.IsTrue:Boolean:True string methodNameText = groupedMatches[1].Value; string parametersText = groupedMatches[5].Value; MethodMapping methodMapping = metaModel.Conditions[methodNameText]; MethodNameExpression methodNameExpression = MethodNameExpression.Parse(metaModel, methodNameText); Parameters parameters = Parameters.Parse(metaModel, methodMapping.EnumParameterTypes, parametersText); return(new ConditionExpression(methodNameExpression, parameters)); }
public static ActionExpression Parse(Metamodel metaModel, string expressionText) { Match match = FullMatch(Syntax.Action, expressionText); if (match == null) { throw new Exception($"Unmatched {nameof(ActionExpression)} {expressionText}"); } ; MethodNameExpression methodNameExpression = MethodNameExpression.Parse(metaModel, match.Groups[1].Value); MethodMapping methodMapping = metaModel.Actions[methodNameExpression.ToString()]; Parameters parameters = Parameters.Parse(metaModel, methodMapping.EnumParameterTypes, match.Groups[5].Value); return(new ActionExpression(methodNameExpression, parameters)); }
/// <summary> /// Specifies how to transform the resulting call of the subject to the proxy result. /// </summary> /// <param name="transform">The transform.</param> /// <returns>The proxy build object</returns> /// <remarks>TODO: Refine documentation</remarks> public IWithSetRedirector <TSubject, TProxy, TSubjectResult, TProxyResult> WithGetter(Func <TSubjectResult, TProxyResult> transform) { var mapping = new MethodMapping() { Name = "get_" + this.pendingMapping.Name, Subject = (subject, parameters) => { TSubjectResult result = this.accesor(((TSubject)subject)); return(transform(result)); }, ArgumentTypes = Type.EmptyTypes, GenericArgumentTypes = Type.EmptyTypes }; this.map.Add(mapping); return(this); }
public void TestIfANotFoundPropertyCanBeRedirected() { // Arrange var generator = new ProxyGenerator(); InterfaceMap map = new InterfaceMap() { Subject = new MoreProperties() { UnmappedProperty = "5" } }; MethodMapping mapping = new MethodMapping() { Subject = (proxied, parameters) => { MoreProperties subject = (MoreProperties)proxied; return(int.Parse(subject.UnmappedProperty)); }, Name = "get_ExtraGetProperty", ArgumentTypes = Type.EmptyTypes, GenericArgumentTypes = Type.EmptyTypes }; map.Add(mapping); MatchingInterceptor <IMoreProperties> interceptor = new MatchingInterceptor <IMoreProperties>(map); int expected = 5; int actual = 0; // Act IMoreProperties proxy = generator.CreateInterfaceProxyWithoutTarget <IMoreProperties>(interceptor); TestDelegate getter = () => { actual = proxy.ExtraGetProperty; }; // Assert Assert.That(proxy, Is.Not.Null); Assert.That(getter, Throws.Nothing); Assert.That(actual, Is.EqualTo(expected)); }
/// <summary> /// Sets the function for transforming from the proxy result type to the subject result type /// </summary> /// <param name="transform">The transform.</param> /// <returns>The proxy builder object</returns> /// <remarks>TODO: Refine documentation</remarks> public IWithGetRedirector <TSubject, TProxy, TSubjectResult, TProxyResult> WithSetter( Func <TProxyResult, TSubjectResult> transform) { var mapping = new MethodMapping() { Name = "set_" + this.pendingMapping.Name, ArgumentTypes = new Type[] { typeof(TProxyResult) }, GenericArgumentTypes = Type.EmptyTypes, Subject = (subject, parameters) => { TProxyResult argument = (TProxyResult)(parameters[0]); TSubjectResult result = transform(argument); TSubject source = (TSubject)subject; this.setter(source, result); return(null); } }; this.map.Add(mapping); return(this); }
/// <summary> /// Gets the expression invocation info. /// </summary> /// <typeparam name="TProxy">The type of the Proxy.</typeparam> /// <typeparam name="TResult">The type of the Result.</typeparam> /// <param name="invocation">The invocation expression.</param> /// <returns>The filled in MethodMapping with pending Subject</returns> /// <exception cref="System.InvalidOperationException">If the invocation is not a method or property call</exception> protected static MethodMapping GetMemberAccessInfo <TProxy, TResult>(Expression <Func <TProxy, TResult> > invocation) where TProxy : class { MethodMapping info = new MethodMapping(); Expression expression = invocation.Body; switch (expression.NodeType) { case ExpressionType.MemberAccess: { MemberExpression specificExpression = (MemberExpression)invocation.Body; MemberInfo member = specificExpression.Member; if (member.MemberType == MemberTypes.Property) { info.ArgumentTypes = Type.EmptyTypes; info.GenericArgumentTypes = Type.EmptyTypes; info.Name = member.Name; } } break; case ExpressionType.Call: { MethodCallExpression specificExpression = (MethodCallExpression)invocation.Body; MethodInfo method = specificExpression.Method; info.ArgumentTypes = GetArgumentTypes(method); info.GenericArgumentTypes = GetGenericArgumentTypes(method); info.Name = method.Name; } break; default: throw new InvalidOperationException(string.Format("Cant redirect expression with a node: {0}", invocation.Body.NodeType)); } return(info); }
protected override Expression VisitNew(NewExpression nex) { nex = base.VisitNew(nex) as NewExpression; var lambda = MethodMapping.ConvertMember(nex.Constructor); if (lambda != null) { var ef = lambda.Body.Unwrap(); var parms = new Dictionary <string, ParameterMapping>(lambda.Parameters.Count); var pn = 0; foreach (var p in lambda.Parameters) { parms.Add(p.Name, new ParameterMapping(pn++, p.Type)); } return(ef.Convert(wpi => { if (wpi.NodeType == ExpressionType.Parameter) { var pe = (ParameterExpression)wpi; var n = parms[pe.Name]; var tmp = nex.Arguments[n.Index]; if (tmp.Type != n.Type) { return Expression.Convert(tmp, n.Type); } return tmp; } return wpi; })); } return(nex); }
private void Update(MemberInitExpression expression, ExpressionParameter parameter) { int i = 0; foreach (MemberBinding binding in expression.Bindings) { ++i; if (binding.BindingType != MemberBindingType.Assignment) { throw new NotSupportedException(); } MemberAssignment memberAssignment = (MemberAssignment)binding; var type = expression.Type; var memberName = this.Context.GetDbColumnName(type.Name, memberAssignment.Member.Name); var item = memberAssignment.Expression; //Column IsJson Handler if (memberAssignment.Member.CustomAttributes != null) { var customAttribute = memberAssignment.Member.GetCustomAttribute <SugarColumn>(); if (customAttribute?.IsJson ?? false) { var paramterValue = ExpressionTool.DynamicInvoke(item); var parameterName = AppendParameter(new SerializeService().SerializeObject(paramterValue)); this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); continue; } } if ((item is MemberExpression) && ((MemberExpression)item).Expression == null) { var paramterValue = ExpressionTool.DynamicInvoke(item); string parameterName = AppendParameter(paramterValue); this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); } else if (IsNotMember(item)) { if (base.Context.Result.IsLockCurrentParameter == false) { base.Context.Result.CurrentParameter = parameter; base.Context.Result.IsLockCurrentParameter = true; parameter.IsAppendTempDate(); base.Expression = item; base.Expression = (item as UnaryExpression).Operand; base.Start(); parameter.IsAppendResult(); var result = this.Context.DbMehtods.IIF(new MethodCallExpressionModel() { Args = new List <MethodCallExpressionArgs>() { new MethodCallExpressionArgs() { IsMember = true, MemberName = parameter.CommonTempData.ObjToString() + "=1" }, new MethodCallExpressionArgs() { IsMember = true, MemberName = AppendParameter(0) }, new MethodCallExpressionArgs() { IsMember = true, MemberName = AppendParameter(1) } } }); parameter.Context.Result.Append(base.Context.GetEqString(memberName, result)); base.Context.Result.CurrentParameter = null; } } else if (IsNotParameter(item)) { try { parameter.Context.Result.Append(base.Context.GetEqString(memberName, AppendParameter(ExpressionTool.DynamicInvoke(item).ObjToBool()))); } catch { throw new NotSupportedException(item.ToString()); } } else if (IsMethod(item)) { if (item is UnaryExpression) { item = (item as UnaryExpression).Operand; } var callMethod = item as MethodCallExpression; if (MethodTimeMapping.Any(it => it.Key == callMethod.Method.Name) || MethodMapping.Any(it => it.Key == callMethod.Method.Name) || IsExtMethod(callMethod.Method.Name) || IsSubMethod(callMethod) || callMethod.Method.DeclaringType.FullName.StartsWith(UtilConstants.AssemblyName + UtilConstants.Dot)) { MethodCall(parameter, memberName, item); } else { var paramterValue = ExpressionTool.DynamicInvoke(item); string parameterName = AppendParameter(paramterValue); this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); } } else if (IsConst(item) && IsConvert(item) && UtilMethods.IsNullable(item.Type) && UtilMethods.GetUnderType(item.Type) == UtilConstants.BoolType) { item = (item as UnaryExpression).Operand; parameter.Context.Result.Append(base.Context.GetEqString(memberName, GetNewExpressionValue(item))); } else if (IsConst(item)) { base.Expression = item; base.Start(); string parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex; parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); var addItem = new SugarParameter(parameterName, parameter.CommonTempData); var dataType = UtilMethods.GetUnderType(item.Type); if (addItem.Value == null && dataType == UtilConstants.DateType) { addItem.DbType = System.Data.DbType.Date; } this.Context.Parameters.Add(addItem); this.Context.ParameterIndex++; } else if (item is MemberExpression) { if (base.Context.Result.IsLockCurrentParameter == false) { base.Context.Result.CurrentParameter = parameter; base.Context.Result.IsLockCurrentParameter = true; parameter.IsAppendTempDate(); base.Expression = item; base.Start(); parameter.IsAppendResult(); parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameter.CommonTempData.ObjToString())); base.Context.Result.CurrentParameter = null; } } else if (item is BinaryExpression) { var result = GetNewExpressionValue(item); if (result.HasValue()) { result = result.Replace(",", UtilConstants.ReplaceCommaKey); } this.Context.Result.Append(base.Context.GetEqString(memberName, result)); } else if (item is MemberInitExpression) { try { var value = ExpressionTool.DynamicInvoke(item); var parameterName = AppendParameter(value); parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); } catch (Exception ex) { throw new NotSupportedException("Not Supported " + item.ToString() + " " + ex.Message); } } else if (item is NewExpression) { try { var value = ExpressionTool.DynamicInvoke(item); var parameterName = AppendParameter(value); parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); } catch (Exception ex) { throw new NotSupportedException("Not Supported " + item.ToString() + " " + ex.Message); } } else if (item is ConditionalExpression) { var result = GetNewExpressionValue(item); this.Context.Result.Append(base.Context.GetEqString(memberName, result)); } } }
private void Update(MemberInitExpression expression, ExpressionParameter parameter) { int i = 0; foreach (MemberBinding binding in expression.Bindings) { ++i; if (binding.BindingType != MemberBindingType.Assignment) { throw new NotSupportedException(); } MemberAssignment memberAssignment = (MemberAssignment)binding; var type = expression.Type; var memberName = this.Context.GetDbColumnName(type.Name, memberAssignment.Member.Name); var item = memberAssignment.Expression; if ((item is MemberExpression) && ((MemberExpression)item).Expression == null) { var paramterValue = ExpressionTool.DynamicInvoke(item); string parameterName = AppendParameter(paramterValue); this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); } else if (IsMethod(item)) { if (item is UnaryExpression) { item = (item as UnaryExpression).Operand; } var callMethod = item as MethodCallExpression; if (MethodTimeMapping.Any(it => it.Key == callMethod.Method.Name) || MethodMapping.Any(it => it.Key == callMethod.Method.Name) || IsExtMethod(callMethod.Method.Name) || IsSubMethod(callMethod) || callMethod.Method.DeclaringType.FullName.StartsWith(UtilConstants.AssemblyName + UtilConstants.Dot)) { MethodCall(parameter, memberName, item); } else { var paramterValue = ExpressionTool.DynamicInvoke(item); string parameterName = AppendParameter(paramterValue); this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); } } else if (IsConst(item)) { base.Expression = item; base.Start(); string parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex; parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); this.Context.Parameters.Add(new SugarParameter(parameterName, parameter.CommonTempData)); this.Context.ParameterIndex++; } else if (item is MemberExpression) { if (base.Context.Result.IsLockCurrentParameter == false) { base.Context.Result.CurrentParameter = parameter; base.Context.Result.IsLockCurrentParameter = true; parameter.IsAppendTempDate(); base.Expression = item; base.Start(); parameter.IsAppendResult(); parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameter.CommonTempData.ObjToString())); base.Context.Result.CurrentParameter = null; } } else if (item is BinaryExpression) { var result = GetNewExpressionValue(item); this.Context.Result.Append(base.Context.GetEqString(memberName, result)); } } }
public MethodCallExpressionResolve(ExpressionParameter parameter) : base(parameter) { var express = base.Expression as MethodCallExpression; var isLeft = parameter.IsLeft; string methodName = express.Method.Name; var isValidNativeMethod = MethodMapping.ContainsKey(methodName) && express.Method.DeclaringType.Namespace == ("System"); List <MethodCallExpressionArgs> appendArgs = null; if (MethodTimeMapping.ContainsKey(methodName)) { appendArgs = new List <MethodCallExpressionArgs>(); var dateType = MethodTimeMapping[methodName]; string paramterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex; appendArgs.Add(new MethodCallExpressionArgs() { IsMember = false, MemberName = paramterName, MemberValue = dateType }); this.Context.Parameters.Add(new SugarParameter(paramterName, dateType.ToString())); this.Context.ParameterIndex++; methodName = "DateAdd"; isValidNativeMethod = true; } else if (methodName == "get_Item") { string paramterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex; this.Context.Parameters.Add(new SugarParameter(paramterName, ExpressionTool.DynamicInvoke(express))); this.Context.Result.Append(string.Format(" {0} ", paramterName)); this.Context.ParameterIndex++; return; } else if (methodName == "NewGuid") { this.Context.Result.Append(this.Context.DbMehtods.GuidNew()); return; } else if (IsSubMethod(express, methodName)) { //Check.Exception(!(parameter.BaseExpression is BinaryExpression), "Current expressions are not supported"); SubResolve subResolve = new SubResolve(express, this.Context, parameter.OppsiteExpression); var appendSql = subResolve.GetSql(); if (this.Context.ResolveType.IsIn(ResolveExpressType.SelectMultiple, ResolveExpressType.SelectSingle)) { parameter.BaseParameter.CommonTempData = appendSql; } else { base.AppendValue(parameter, isLeft, appendSql); } return; } if (IsContainsArray(express, methodName, isValidNativeMethod)) { methodName = "ContainsArray"; isValidNativeMethod = true; } if (isValidNativeMethod) { NativeExtensionMethod(parameter, express, isLeft, MethodMapping[methodName], appendArgs); } else { SqlFuncMethod(parameter, express, isLeft); } }
protected override Expression VisitMemberAccess(MemberExpression m) { m = base.VisitMemberAccess(m) as MemberExpression; var expression = m.Expression; var l = MethodMapping.ConvertMember(m.Member); if (l != null) { var body = l.Body.Unwrap(); var expr = body.Convert(wpi => wpi.NodeType == ExpressionType.Parameter ? expression : wpi); if (expr.Type != m.Type) { expr = Expression.Convert(expr, m.Type); } return(expr); } if (m.Member.DeclaringType == typeof(TimeSpan)) { switch (expression.NodeType) { case ExpressionType.Subtract: case ExpressionType.SubtractChecked: DateParts datePart; switch (m.Member.Name) { case "TotalMilliseconds": case "TotalSeconds": case "TotalMinutes": case "TotalHours": case "TotalDays": throw new NotSupportedException(string.Format("The member access '{0}' is not supported", m.Member)); case "Milliseconds": datePart = DateParts.Millisecond; break; case "Seconds": datePart = DateParts.Second; break; case "Minutes": datePart = DateParts.Minute; break; case "Hours": datePart = DateParts.Hour; break; case "Days": datePart = DateParts.Day; break; default: return(m); } var ex = (BinaryExpression)expression; var call = Expression.Call( DateDiffMethod, Expression.Constant(datePart), Expression.Convert(ex.Left, typeof(DateTime)), Expression.Convert(ex.Right, typeof(DateTime))); return(Visit(call)); } } return(m); }
protected override Expression VisitMethodCall(MethodCallExpression m) { m = base.VisitMethodCall(m) as MethodCallExpression; var lambda = MethodMapping.ConvertMember(m.Method); if (lambda != null) { var ef = lambda.Body.Unwrap(); var parms = new Dictionary <string, ParameterMapping>(lambda.Parameters.Count); var pn = m.Method.IsStatic ? 0 : -1; foreach (var p in lambda.Parameters) { parms.Add(p.Name, new ParameterMapping(pn++, p.Type)); } var pie = ef.Convert(wpi => { if (wpi.NodeType == ExpressionType.Parameter) { ParameterMapping n; if (parms.TryGetValue(((ParameterExpression)wpi).Name, out n)) { var tmp = n.Index < 0 ? m.Object : m.Arguments[n.Index]; if (tmp.Type != n.Type) { return(Expression.Convert(tmp, n.Type)); } return(tmp); } } return(wpi); }); if (m.Method.ReturnType != pie.Type) { pie = Expression.Convert(pie, m.Method.ReturnType); } return(Visit(pie)); } var methodName = m.Method.Name; var declaringType = m.Method.DeclaringType; if (declaringType == typeof(System.Convert)) { Expression operand = null; Type toType = null; if (m.Method.Name.StartsWith("To")) { toType = ClassLoader.Load("System." + m.Method.Name.Replace("To", "")); operand = m.Arguments[0]; } if (operand != null && toType != null && toType != Types.Object) { return(Expression.Call(MethodRepository.GetConvertMethod(operand.Type, toType), operand)); } } if (typeof(TypeConverter).IsAssignableFrom(declaringType)) { Expression operand = null; Type toType = null; if (methodName.StartsWith("ConvertFrom")) { var c = m.Object as ConstantExpression; Type converterType = null; if (c != null) { converterType = (m.Object as ConstantExpression).Value.GetType(); } else { var ma = m.Object as MemberExpression; if (ma != null) { c = ma.Expression as ConstantExpression; if (c == null) { throw new NotSupportedException(string.Format("The method '{0}' is not supported", m.Method.Name)); } converterType = ma.Member.GetGetter()(c.Value).GetType(); } } toType = ClassLoader.Load("System." + converterType.Name.Replace("Converter", "")); if (toType == null) { throw new NotSupportedException(string.Format("The method '{0}' is not supported", m.Method.Name)); } if (methodName == "ConvertFrom" && m.Arguments.Count == 1) { operand = m.Arguments[0]; } else if (methodName == "ConvertFromString" && m.Arguments.Count == 1) { operand = m.Arguments[0]; } else if (methodName == "ConvertFromInvariantString" && m.Arguments.Count == 1) { operand = m.Arguments[0]; } } else if (methodName == "ConvertTo" && m.Arguments.Count == 2) { operand = m.Arguments[0]; toType = (m.Arguments[1] as ConstantExpression).Value as Type; } else if (methodName == "ConvertToInvariantString" && m.Arguments.Count == 1) { operand = m.Arguments[0]; toType = Types.String; } else if (methodName == "ConvertToString" && m.Arguments.Count == 1) { operand = m.Arguments[0]; toType = Types.String; } if (operand != null && toType != null && toType != Types.Object) { return(Expression.Call(MethodRepository.GetConvertMethod(operand.Type, toType), operand)); } throw new NotSupportedException(string.Format("The method '{0}' is not supported", methodName)); } if (methodName == "Parse" && m.Method.IsStatic && (declaringType.IsValueType || declaringType.IsNullable()) && m.Arguments.Count == 1 && m.Method.ReturnType == m.Type) { Expression operand = m.Arguments[0]; Type toType = declaringType.IsNullable() ? Nullable.GetUnderlyingType(declaringType) : declaringType; return(Expression.Call(MethodRepository.GetConvertMethod(operand.Type, toType), operand)); } if (declaringType == Types.String) { if (methodName == "Concat") { return(BindConcat(m.Arguments.ToArray())); } if (methodName == "Join") { return(BindJoin(m)); } } if (methodName == "ContainsValue" && IsSameOrParent(typeof(IDictionary <,>), declaringType)) { var args = GetGenericArguments(declaringType, typeof(IDictionary <,>)); var minf = EnumerableMethods .First(s => s.Name == "Contains" && s.GetParameters().Length == 2) .MakeGenericMethod(args[1]); return(Expression.Call( minf, Expression.PropertyOrField(m.Object, "Values"), m.Arguments[0])); } if (methodName == "ContainsKey" && IsSameOrParent(typeof(IDictionary <,>), declaringType)) { var args = GetGenericArguments(declaringType, typeof(IDictionary <,>)); var minf = EnumerableMethods .First(s => s.Name == "Contains" && s.GetParameters().Length == 2) .MakeGenericMethod(args[1]); return(Expression.Call( minf, Expression.PropertyOrField(m.Object, "Keys"), m.Arguments[0])); } if (declaringType.FullName == DLinq.StrSqlMethhodsType && declaringType.Assembly.GetName().Name == DLinq.StrAssemblyName) { DLinq.Init(declaringType.Assembly); return(Visit(m)); } //if (methodName == "Like" && declaringType == typeof(SqlFunctions) && m.Arguments.Count == 5) //{ // return BindLike( // m.Arguments[0] // , m.Arguments[1] // , (bool)(m.Arguments[2] as ConstantExpression).Value // , (bool)(m.Arguments[3] as ConstantExpression).Value // , (bool)(m.Arguments[4] as ConstantExpression).Value); //} if (typeof(Queryable).IsAssignableFrom(declaringType) || typeof(Enumerable).IsAssignableFrom(declaringType)) { var elementType = NLite.Data.Linq.Internal.ReflectionHelper.GetElementType(m.Arguments[0].Type); switch (methodName) { case "Contains": EntityMapping mapping; if (DbContext.dbConfiguration.mappings.TryGetValue(elementType.TypeHandle.Value, out mapping)) { // Expression left = } break; //case "Aggregate": // { // var type = NLite.Reflection.TypeHelper.GetElementType(m.Arguments[0].Type); // if (type.IsNullable()) // type = Nullable.GetUnderlyingType(type); // if (type.IsClass && type != Types.String) // throw new NotSupportedException("Not support 'Aggregate' function for complex type."); // break; // } //case "ElementAt": // var index = m.Arguments[1]; // var elementType = NLite.Reflection.TypeHelper.GetElementType(m.Arguments[0].Type); // var c = index as ConstantExpression; // if (c != null) // { // if((int)c.Value == 0) // return Expression.Call(typeof(Enumerable), "Take", new Type[] { elementType }, m.Arguments[0], Expression.Constant(1, Types.Int32)); // index = Expression.Constant((int)c.Value + 1, Types.Int32); // } // else // index = Expression.Add(index, Expression.Constant(1, Types.Int32)); // var s = Expression.Call(typeof(Enumerable), "Skip", new Type[] { elementType },m.Arguments[0], index); // return Expression.Call(typeof(Enumerable), "Take", new Type[] { elementType },s, Expression.Constant(1,Types.Int32)); } } if (IsSameOrParent(typeof(IEnumerable <>), declaringType) && !declaringType.IsArray && m.Object != null && m.Object.NodeType == ExpressionType.Constant && !typeof(IQueryable).IsAssignableFrom(declaringType)) { switch (methodName) { case "Contains": var elementType = NLite.Data.Linq.Internal.ReflectionHelper.GetElementType(declaringType); if (!DbContext.dbConfiguration.HasClass(elementType) && elementType != Types.Char) { var lst = (m.Object as ConstantExpression).Value as IEnumerable; if (lst != null) { var items = lst.Cast <object>().ToArray(); var arry = Array.CreateInstance(elementType, items.Length); for (int i = 0; i < items.Length; i++) { arry.SetValue(items[i], i); } Expression array = Expression.Constant(arry); var containsMethod = EnumerableMethods .First(s => s.Name == "Contains" && s.GetParameters().Length == 2) .MakeGenericMethod(elementType); m = Expression.Call(containsMethod, array, m.Arguments[0]); } } break; } } return(m); }
private bool IsValidNativeMethod(MethodCallExpression express, string methodName) { return(MethodMapping.ContainsKey(methodName) && express.Method.DeclaringType.Namespace == ("System")); }
/// <summary> /// Map methods to actions. /// </summary> /// <param name="info">Method to inspect.</param> /// <remarks>Goes through all custom action attributes to check which HTTP methods /// the action is valid for.</remarks> /// <exception cref="ActionMappingException">Mapping collision. Do not both suffix methods with a verb and use ValidFor attribute.</exception> private void MapMethod(MethodInfo info) { string verb; string methodName = info.Name; bool isFound = TryGetVerb(ref methodName, out verb); MethodMapping mapping; if (!_methods.TryGetValue(methodName.ToLower(), out mapping)) { mapping = new MethodMapping(); _methods.Add(methodName.ToLower(), mapping); } // specified a verb if (isFound) { _logger.Trace("Mapped " + _uri + "." + methodName.ToLower() + " to " + verb); mapping.IsMethodsSpecified = true; mapping.Add(verb, info); } // Check if method is valid only for a few verbs foreach (object customAttribute in info.GetCustomAttributes(false)) { var attr = customAttribute as ValidForAttribute; if (attr == null) continue; if (isFound) throw new ActionMappingException( "Mapping collision. Do not both suffix methods with a verb and use ValidFor attribute."); mapping.IsMethodsSpecified = true; } if (!mapping.IsMethodsSpecified) { _logger.Trace("Mapped " + _uri + "." + methodName.ToLower() + " to ALL verbs"); mapping.Add(verb, info); } }
public static void Init(Assembly asm) { var instance = new ULinq(); //var asm = linqToSqlClassType.Assembly; EntityRefType = asm.GetType(StrEntityRefType); EntitySetType = asm.GetType(StrEntitySetType); BinaryType = asm.GetType(StrBinaryType); BinaryCtor = BinaryType.GetConstructor(new Type[] { typeof(byte[]) }).GetCreator(); SqlType.TypeMap[BinaryType.TypeHandle.Value.GetHashCode()] = DBType.Binary; instance.Table = new TableAttribute(); instance.Table.Type = asm.GetType(ULinq.StrTableAttributeType); instance.Table.Name = instance.Table.Type.GetProperty("Name").GetGetter(); instance.Column = new ColumnAttribute(); instance.Column.Type = asm.GetType(ULinq.StrColumnAttributeType); instance.Column.Name = instance.Column.Type.GetProperty("Name").GetGetter(); instance.Column.CanBeNull = instance.Column.Type.GetProperty("CanBeNull").GetGetter(); instance.Column.IsDbGenerated = instance.Column.Type.GetProperty("IsDbGenerated").GetGetter(); instance.Column.IsPrimaryKey = instance.Column.Type.GetProperty("IsPrimaryKey").GetGetter(); instance.Column.IsVersion = instance.Column.Type.GetProperty("IsVersion").GetGetter(); instance.Column.AutoSync = instance.Column.Type.GetProperty("AutoSync").GetGetter(); instance.Column.DbType = instance.Column.Type.GetProperty("DbType").GetGetter(); instance.Column.Expression = instance.Column.Type.GetProperty("Expression").GetGetter(); instance.Column.IsDiscriminator = instance.Column.Type.GetProperty("IsDiscriminator").GetGetter(); instance.Column.Storage = instance.Column.Type.GetProperty("Storage").GetGetter(); instance.Column.UpdateCheck = instance.Column.Type.GetProperty("UpdateCheck").GetGetter(); instance.Association = new AssociationAttribute(); instance.Association.Type = asm.GetType(ULinq.StrAssociationAttributeType); instance.Association.ThisKey = instance.Association.Type.GetProperty("ThisKey").GetGetter(); instance.Association.OtherKey = instance.Association.Type.GetProperty("OtherKey").GetGetter(); instance.Association.IsForeignKey = instance.Association.Type.GetProperty("IsForeignKey").GetGetter(); var sqlMethodsType = asm.GetType(ULinq.StrSqlMethhodsType); //var flags = BindingFlags.Public | BindingFlags.Static; var dateDiffDay = sqlMethodsType.GetMethod("DateDiffDay", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffDay] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Day, startTime, endTime)); var dateDiffHour = sqlMethodsType.GetMethod("DateDiffHour", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffHour] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Hour, startTime, endTime)); var dateDiffMicrosecond = sqlMethodsType.GetMethod("DateDiffMicrosecond", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffMicrosecond] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Microsecond, startTime, endTime)); var dateDiffMillisecond = sqlMethodsType.GetMethod("DateDiffMillisecond", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffMillisecond] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Millisecond, startTime, endTime)); var dateDiffMinute = sqlMethodsType.GetMethod("DateDiffMinute", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffMinute] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Minute, startTime, endTime)); var dateDiffMonth = sqlMethodsType.GetMethod("DateDiffMonth", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffMonth] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Month, startTime, endTime)); var dateDiffNanosecond = sqlMethodsType.GetMethod("DateDiffNanosecond", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffNanosecond] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Nanosecond, startTime, endTime)); var dateDiffSecond = sqlMethodsType.GetMethod("DateDiffSecond", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffSecond] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Second, startTime, endTime)); var dateDiffYear = sqlMethodsType.GetMethod("DateDiffYear", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffYear] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Year, startTime, endTime)); // var dateDiffDayForNullable = sqlMethodsType.GetMethod("DateDiffDay", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffDayForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Day, startTime, endTime)); var dateDiffHourForNullable = sqlMethodsType.GetMethod("DateDiffHour", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffHourForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Hour, startTime, endTime)); var dateDiffMicrosecondForNullable = sqlMethodsType.GetMethod("DateDiffMicrosecond", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffMicrosecondForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Microsecond, startTime, endTime)); var dateDiffMillisecondForNullable = sqlMethodsType.GetMethod("DateDiffMillisecond", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffMillisecondForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Millisecond, startTime, endTime)); var dateDiffMinuteForNullable = sqlMethodsType.GetMethod("DateDiffMinute", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffMinuteForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Minute, startTime, endTime)); var dateDiffMonthForNullable = sqlMethodsType.GetMethod("DateDiffMonth", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffMonthForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Month, startTime, endTime)); var dateDiffNanosecondForNullable = sqlMethodsType.GetMethod("DateDiffNanosecond", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffNanosecondForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Nanosecond, startTime, endTime)); var dateDiffSecondForNullable = sqlMethodsType.GetMethod("DateDiffSecond", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffSecondForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Second, startTime, endTime)); var dateDiffYearForNullable = sqlMethodsType.GetMethod("DateDiffYear", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffYearForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Year, startTime, endTime)); Instance = instance; }