public LambdaExpression ParseSelectList(Type thisType, string selectListExpression, bool useAnonymousType = true) { // By enclosing the selectListExpression in a method call, we can use the same parser // as for filter queries, then we convert each part of the select statement to a // lambda expression. var symbolTree = ParseSymbolTree($"select({selectListExpression})"); var thisParam = Expression.Parameter(thisType, "_this"); var selectParts = symbolTree.Children.Select(x => ParseSelectPart(thisType, x, thisParam, selectListExpression)).ToList(); if (selectParts.Count == 1 && selectParts[0].Key.ToLower() == "this") { // This is a way to select a list of one property, without encapsulating it inside anon objects.. return(Expression.Lambda(selectParts[0].Value, thisParam)); } if (useAnonymousType) { Type anonTypeInstance; var expr = AnonymousTypeBuilder.CreateNewExpression(selectParts, out anonTypeInstance); return(Expression.Lambda(expr, thisParam)); } var addMethod = ReflectionHelper.GetMethodDefinition <Dictionary <string, object> >(x => x.Add("", null)); var dictExpr = Expression.ListInit(Expression.New(typeof(Dictionary <string, object>)), selectParts.Select( x => Expression.ElementInit( addMethod, Expression.Constant(x.Key), x.Value.Type.IsValueType ? Expression.Convert(x.Value, typeof(object)) : x.Value))); return(Expression.Lambda(dictExpr, thisParam)); }
public void CanCreateSimpleTypeWithProperties() { var anon = AnonymousTypeBuilder.DefineType().WithProperty("name", "Fred").WithProperty("age", 30033).Instance(); Assert.That(anon.GetType().GetProperty("name").GetValue(anon), Is.EqualTo("Fred")); Assert.That(anon.GetType().GetProperty("age").GetValue(anon), Is.EqualTo(30033)); }
public override (Expression, ExpressionConversionResult) Convert(Esprima.Ast.ObjectExpression objectExpression, ExpressionConverterContext context, ExpressionConverterScope scope, bool allowTerminal, params Type[] genericArguments) { if (scope.TargetType != null) { var code = context.Source.Substring(objectExpression.Range.Start, objectExpression.Range.End - objectExpression.Range.Start + 1); using (var reader = new StringReader(code)) { var @object = JsonSerializer.Deserialize(reader, scope.TargetType); return(Expression.Constant(@object), DefaultResult); } } var propertyValueExpressions = objectExpression.Properties.Select(property => new { Property = property, ValueExpression = context.ExpressionConverterResolver.Convert(property.Value, context, scope, false) }).ToArray(); var tuples = propertyValueExpressions.Select(propertyValueExpression => new Tuple <Type, string>(propertyValueExpression.ValueExpression.Type, ((Esprima.Ast.Identifier)propertyValueExpression.Property.Key).Name)).ToArray(); var set = new HashSet <Tuple <Type, string> >(tuples); Type anonymousType = null; if (!Cache.TryGetValue(set, out anonymousType)) { anonymousType = AnonymousTypeBuilder.BuildAnonymousType(set); Cache[set] = anonymousType; } var newExpression = Expression.New(anonymousType.GetConstructor(new Type[0])); var initializationExpression = Expression.MemberInit( newExpression, propertyValueExpressions.Select(pve => Expression.Bind(anonymousType.GetProperty(((Esprima.Ast.Identifier)pve.Property.Key).Name), pve.ValueExpression)) ); return(initializationExpression, DefaultResult); }
public NewExpressionConverter(AnonymousTypeBuilder anonymousTypeBuilder, JsonSerializer jsonSerializer) : base() { AnonymousTypeBuilder = anonymousTypeBuilder; var comparer = HashSet <Tuple <Type, string> > .CreateSetComparer(); Cache = new Dictionary <HashSet <Tuple <Type, string> >, Type>(comparer); JsonSerializer = jsonSerializer; }
public void WriteAssemblyToFileForDebugging() { var tb = new AnonymousTypeBuilder(new[] { "Foo", "Bar" }); var def = tb.BuildAnonymousType(); def.Module.Assembly.Write("tempasm.dll"); Assert.Fail("TODO: Remove me"); }
public void CanCreateFromAnExpandoObjectDictionary() { var source = new Dictionary <string, object> { { "name", "Fred" }, { "age", 30033 } }; var anon = AnonymousTypeBuilder.FromDictionary(source); Assert.That(anon.GetType().GetProperty("name").GetValue(anon), Is.EqualTo("Fred")); Assert.That(anon.GetType().GetProperty("age").GetValue(anon), Is.EqualTo(30033)); }
public OrderedQueryableGenericRuleMap(AnonymousTypeBuilder anonymousTypeBuilder, IModel model) : base(typeof(IOrderedQueryable <>), new Type[] { null }, anonymousTypeBuilder, model) { HasMethodPermissionResolver <Func <Expression <Func <object, object> >, IQueryable <object> > >(query => query.Select, context => Permission.Read, new Type[] { null, null }); HasMethodPermissionResolver <Func <Expression <Func <object, bool> >, IQueryable <object> > >(query => query.Where, context => Permission.Read, new Type[] { null }); HasMethodPermissionResolver <Func <int, IQueryable <object> > >(query => query.Skip, context => Permission.Read, new Type[] { null }); HasMethodPermissionResolver <Func <int, IQueryable <object> > >(query => query.Take, context => Permission.Read, new Type[] { null }); HasMethodPermissionResolver <Func <IQueryable <object> > >(query => query.Distinct, context => Permission.Read, new Type[] { null }); HasMethodPermissionResolver <Func <Expression <Func <object, bool> >, bool> >(query => query.Any, context => Permission.Read, new Type[] { null }); HasMethodPermissionResolver <Func <bool> >(query => query.Any, context => Permission.Read, new Type[] { null }); HasMethodPermissionResolver <Func <Expression <Func <object, bool> >, bool> >(query => query.All, context => Permission.Read, new Type[] { null }); HasMethodPermissionResolver <Func <int> >(query => query.Count, context => Permission.Read, new Type[] { null }); HasMethodPermissionResolver <Func <Expression <Func <object, IEnumerable <object> > >, IQueryable <object> > >(query => query.SelectMany, context => Permission.Read, new Type[] { null, null }); HasMethodPermissionResolver <Func <Expression <Func <object, object> >, IOrderedQueryable <object> > >(query => query.OrderBy, context => Permission.Read, new Type[] { null, null }); HasMethodPermissionResolver <Func <Expression <Func <object, object> >, IOrderedQueryable <object> > >(query => query.OrderByDescending, context => Permission.Read, new Type[] { null, null }); HasMethodPermissionResolver <Func <Expression <Func <object, object> >, IOrderedQueryable <object> > >(query => query.ThenBy, context => Permission.Read, new Type[] { null, null }); HasMethodPermissionResolver <Func <Expression <Func <object, object> >, IOrderedQueryable <object> > >(query => query.ThenByDescending, context => Permission.Read, new Type[] { null, null }); //DisableProjectionForMethod<Func<Expression<Func<object, object>>, IQueryable<object>>>(query => query.Select, new Type[] { null, null }); //DisableProjectionForMethod<Func<Expression<Func<object, bool>>, IQueryable<object>>>(query => query.Where, new Type[] { null }); //DisableProjectionForMethod<Func<int, IQueryable<object>>>(query => query.Skip, new Type[] { null }); //DisableProjectionForMethod<Func<int, IQueryable<object>>>(query => query.Take, new Type[] { null }); //DisableProjectionForMethod<Func<IQueryable<object>>>(query => query.Distinct, new Type[] { null }); //DisableProjectionForMethod<Func<Expression<Func<object, bool>>, bool>>(query => query.Any, new Type[] { null }); //DisableProjectionForMethod<Func<Expression<Func<object, bool>>, bool>>(query => query.All, new Type[] { null }); //DisableProjectionForMethod<Func<int>>(query => query.Count, new Type[] { null }); //DisableProjectionForMethod<Func<Expression<Func<object, IEnumerable<object>>>, IQueryable<object>>>(query => query.SelectMany, new Type[] { null, null }); //DisableProjectionForMethod<Func<Expression<Func<object, object>>, IOrderedQueryable<object>>>(query => query.OrderBy, new Type[] { null, null }); //DisableProjectionForMethod<Func<Expression<Func<object, object>>, IOrderedQueryable<object>>>(query => query.OrderByDescending, new Type[] { null, null }); //DisableProjectionForMethod<Func<Expression<Func<object, object>>, IOrderedQueryable<object>>>(query => query.ThenBy, new Type[] { null, null }); //DisableProjectionForMethod<Func<Expression<Func<object, object>>, IOrderedQueryable<object>>>(query => query.ThenByDescending, new Type[] { null, null }); DisableFilterForMethod <Func <Expression <Func <object, object> >, IQueryable <object> > >(query => query.Select, new Type[] { null, null }); DisableFilterForMethod <Func <Expression <Func <object, bool> >, IQueryable <object> > >(query => query.Where, new Type[] { null }); DisableFilterForMethod <Func <int, IQueryable <object> > >(query => query.Skip, new Type[] { null }); DisableFilterForMethod <Func <int, IQueryable <object> > >(query => query.Take, new Type[] { null }); DisableFilterForMethod <Func <IQueryable <object> > >(query => query.Distinct, new Type[] { null }); DisableFilterForMethod <Func <Expression <Func <object, bool> >, bool> >(query => query.Any, new Type[] { null }); DisableFilterForMethod <Func <bool> >(query => query.Any, new Type[] { null }); DisableFilterForMethod <Func <Expression <Func <object, bool> >, bool> >(query => query.All, new Type[] { null }); DisableFilterForMethod <Func <int> >(query => query.Count, new Type[] { null }); DisableFilterForMethod <Func <Expression <Func <object, IEnumerable <object> > >, IQueryable <object> > >(query => query.SelectMany, new Type[] { null, null }); DisableFilterForMethod <Func <Expression <Func <object, object> >, IOrderedQueryable <object> > >(query => query.OrderBy, new Type[] { null, null }); DisableFilterForMethod <Func <Expression <Func <object, object> >, IOrderedQueryable <object> > >(query => query.OrderByDescending, new Type[] { null, null }); DisableFilterForMethod <Func <Expression <Func <object, object> >, IOrderedQueryable <object> > >(query => query.ThenBy, new Type[] { null, null }); DisableFilterForMethod <Func <Expression <Func <object, object> >, IOrderedQueryable <object> > >(query => query.ThenByDescending, new Type[] { null, null }); }
public RuleMap(AnonymousTypeBuilder anonymousTypeBuilder, IModel model) { PropertyOptions = new Dictionary <PropertyInfo, PropertyOptions <TContext, T> >(new PropertyInfoHandleComparer()); TypePermissionResolvers = new Collection <Func <TContext, Permission> >(); TypeCustomResolvers = new Dictionary <object, ICollection <Func <TContext, object> > >(); InstancePermissionResolvers = new Collection <Func <TContext, T, Permission> >(); InstancePermissionResolverExpressions = new Collection <Expression <Func <TContext, T, Permission> > >(); InstanceCustomResolverExpressions = new Dictionary <object, ICollection <Expression <Func <TContext, T, object> > > >(); InstanceCustomResolverExpressionReducers = new Dictionary <object, Func <Expression, Expression, Expression> >(); InstanceCustomResolvers = new Dictionary <object, ICollection <Func <TContext, T, object> > >(); InstanceCustomResolverReducers = new Dictionary <object, Func <object, object, object> >(); MethodPermissionResolvers = new ParameterizedGenericMethodInfoRuleRegistry(); AnonymousTypeBuilder = anonymousTypeBuilder; PreCreationActions = new Collection <Func <TContext, T, EntityEntry, ActionResult, Task <ActionResult> > >(); PostCreationActions = new Collection <Func <TContext, T, EntityEntry, EntityMutationInfo, Task> >(); PreEditionActions = new Collection <Func <TContext, T, EntityEntry, ActionResult, Task <ActionResult> > >(); PostEditionActions = new Collection <Func <TContext, T, EntityEntry, Task> >(); PreDeletionActions = new Collection <Func <TContext, T, EntityEntry, ActionResult, Task <ActionResult> > >(); PostDeletionActions = new Collection <Func <TContext, T, EntityEntry, Task> >(); Model = model; InstanceOptions = new InstanceOptions <TContext, T>(); }
public UserRuleMap(AnonymousTypeBuilder anonymousTypeBuilder, IModel model) : base(anonymousTypeBuilder, model) { }
internal static Type BuildMapperAssembly(Type mapperInterfaceType) { object name; object obj; BaseMapper.logger.Debug(string.Concat("BuildMapperAssembly ", mapperInterfaceType.FullName), (LogInfo)null, null); string str = string.Concat(mapperInterfaceType.Namespace, ".Concrete"); AppDomain currentDomain = AppDomain.CurrentDomain; AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(str), AssemblyBuilderAccess.Run); string str1 = string.Concat(str, ".", mapperInterfaceType.Name.Substring(1)); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(str1); TypeBuilder typeBuilder = moduleBuilder.DefineType(str1, TypeAttributes.Public, BaseMapper.typeBaseMapper); NameAttribute customAttribute = mapperInterfaceType.GetTypeInfo().GetCustomAttribute <NameAttribute>(); if (customAttribute != null) { name = customAttribute.Name; } else { name = null; } if (name == null) { name = mapperInterfaceType.Name.Substring(1, mapperInterfaceType.Name.Length - "IMapper".Length); } string str2 = (string)name; typeBuilder.AddInterfaceImplementation(mapperInterfaceType); AnonymousTypeBuilder anonymousTypeBuilder = new AnonymousTypeBuilder(assemblyBuilder, moduleBuilder); MethodInfo[] methods = mapperInterfaceType.GetMethods(); for (int i = 0; i < (int)methods.Length; i++) { MethodInfo methodInfo = methods[i]; ParameterInfo[] parameters = methodInfo.GetParameters(); Type[] array = ( from p in (IEnumerable <ParameterInfo>)methodInfo.GetParameters() select p.ParameterType).ToArray <Type>(); List <ParameterAttribute> list = methodInfo.GetCustomAttributes <ParameterAttribute>().ToList <ParameterAttribute>(); MethodBuilder methodBuilder = typeBuilder.DefineMethod(methodInfo.Name, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.VtableLayoutMask | MethodAttributes.NewSlot, CallingConventions.Standard, methodInfo.ReturnType, array); for (byte j = 0; j < (int)array.Length; j = (byte)(j + 1)) { methodBuilder.DefineParameter(j + 1, ParameterAttributes.None, parameters[j].Name); } ILGenerator lGenerator = methodBuilder.GetILGenerator(); if (methodInfo.ReturnType != typeof(void)) { lGenerator.DeclareLocal(methodInfo.ReturnType); } lGenerator.Emit(OpCodes.Nop); lGenerator.Emit(OpCodes.Ldarg_0); lGenerator.Emit(OpCodes.Call, BaseMapper.typeBaseMapper.GetMethod("get_Provider", BindingFlags.Instance | BindingFlags.Public)); NameAttribute nameAttribute = methodInfo.GetCustomAttribute <NameAttribute>(); if (nameAttribute != null) { obj = nameAttribute.Name; } else { obj = null; } if (obj == null) { obj = string.Concat(str2, ".", methodInfo.Name); } string str3 = (string)obj; lGenerator.Emit(OpCodes.Ldstr, str3); if (array.Length != 0 || list.Count != 0) { sbyte num = 0; bool[] flagArray = new bool[(int)array.Length + list.Count]; for (byte k = 0; k < (int)array.Length; k = (byte)(k + 1)) { flagArray[k] = array[k].GetTypeInfo().IsSubclassOf(typeof(ValueObject)); if (flagArray[k]) { num = (sbyte)(num + 1); } } for (byte l = 0; l < list.Count; l = (byte)(l + 1)) { flagArray[(int)array.Length + l] = list[l].Parameter.Value.GetType().GetTypeInfo().IsSubclassOf(typeof(ValueObject)); if (flagArray[(int)array.Length + l]) { num = (sbyte)(num + 1); } } Type[] type = new Type[(int)array.Length + list.Count - num]; string[] parameterName = new string[(int)array.Length + list.Count - num]; BaseMapper.EmitHepler(lGenerator, OpCodes.Ldc_I4_S, num + (type.Length == 0 ? 0 : 1)); lGenerator.Emit(OpCodes.Newarr, typeof(object)); lGenerator.Emit(OpCodes.Dup); sbyte num1 = 0; for (byte m = 0; m < (int)array.Length; m = (byte)(m + 1)) { if (!flagArray[m]) { type[m - num1] = array[m]; parameterName[m - num1] = parameters[m].Name; } else { OpCode ldcI4S = OpCodes.Ldc_I4_S; sbyte num2 = num1; num1 = (sbyte)(num2 + 1); BaseMapper.EmitHepler(lGenerator, ldcI4S, num2); BaseMapper.EmitHepler(lGenerator, OpCodes.Ldarg_S, m + 1); lGenerator.Emit(OpCodes.Stelem_Ref); if (m == (int)array.Length - (type.Length == 0 ? 2 : 1)) { lGenerator.Emit(OpCodes.Dup); } } } for (byte n = 0; n < list.Count; n = (byte)(n + 1)) { if (!flagArray[(int)array.Length + n]) { BaseMapper.directParameterValue.Add(string.Concat(str1, ".", methodInfo.Name), list[n].Parameter.Value); type[(int)array.Length + n - num1] = list[n].Parameter.Value.GetType(); parameterName[(int)array.Length + n - num1] = list[n].Parameter.ParameterName; } } if (type.Length != 0) { BaseMapper.EmitHepler(lGenerator, OpCodes.Ldc_I4_S, num); for (byte o = 0; o < (int)array.Length; o = (byte)(o + 1)) { if (!flagArray[o]) { BaseMapper.EmitHepler(lGenerator, OpCodes.Ldarg_S, o + 1); } } for (byte p1 = 0; p1 < list.Count; p1 = (byte)(p1 + 1)) { if (!flagArray[(int)array.Length + p1]) { lGenerator.Emit(OpCodes.Ldsfld, BaseMapper.fieldDirectParameterValue); lGenerator.Emit(OpCodes.Ldstr, string.Concat(str1, ".", methodInfo.Name)); lGenerator.Emit(OpCodes.Callvirt, BaseMapper.methodDirectParameterValue); } } Type type1 = anonymousTypeBuilder.CreateType(type, parameterName); lGenerator.Emit(OpCodes.Newobj, type1.GetConstructors()[0]); lGenerator.Emit(OpCodes.Stelem_Ref); } } else { MethodInfo method = typeof(Array).GetMethod("Empty"); method = method.MakeGenericMethod(new Type[] { typeof(object) }); lGenerator.Emit(OpCodes.Call, method); } CommandItem item = CommandRepository.Instance[str3] ?? new CommandItem() { Verb = CommandVerb.Get }; MethodInfo methodInfo1 = (methodInfo.ReturnType == typeof(void) || item.Verb != CommandVerb.Get ? BaseMapper.methodQuery : BaseMapper.methodScalar); TypeInfo typeInfo = methodInfo.ReturnType.GetTypeInfo(); bool flag = typeInfo.ImplementedInterfaces.Contains <Type>(typeof(IList)); bool flag1 = typeInfo.ImplementedInterfaces.Contains <Type>(typeof(IDictionary)); bool flag2 = typeInfo.IsSubclassOf(typeof(ValueObject)); bool flag3 = false; if (methodInfo.ReturnType == typeof(ValueSet)) { methodInfo1 = BaseMapper.methodDataSet; } else if (methodInfo.ReturnType == typeof(ValueTable)) { methodInfo1 = BaseMapper.methodDataTable; } else if (methodInfo.ReturnType == typeof(ValueRow)) { methodInfo1 = BaseMapper.methodDataRow; } else if (item.Verb == CommandVerb.Get && flag | flag1 | flag2) { methodInfo1 = BaseMapper.methodDataTable; flag3 = true; } if (methodInfo1 == BaseMapper.methodScalar) { methodInfo1 = methodInfo1.MakeGenericMethod(new Type[] { methodInfo.ReturnType }); } lGenerator.Emit(OpCodes.Call, methodInfo1); if (flag3) { MethodInfo methodInfo2 = null; if (!flag) { methodInfo2 = (!flag1 ? BaseMapper.methodToFirstVo.MakeGenericMethod(new Type[] { methodInfo.ReturnType }) : BaseMapper.methodToDictionary.MakeGenericMethod(new Type[] { methodInfo.ReturnType.GenericTypeArguments[0], methodInfo.ReturnType.GenericTypeArguments[1] })); } else { methodInfo2 = BaseMapper.methodToList.MakeGenericMethod(new Type[] { methodInfo.ReturnType.GenericTypeArguments[0] }); } lGenerator.Emit(OpCodes.Call, methodInfo2); } if (methodInfo.ReturnType != typeof(void)) { lGenerator.Emit(OpCodes.Stloc_0); lGenerator.Emit(OpCodes.Br_S, (sbyte)0); lGenerator.Emit(OpCodes.Ldloc_0); } else { lGenerator.Emit(OpCodes.Pop); } lGenerator.Emit(OpCodes.Ret); } return(typeBuilder.CreateTypeInfo().AsType()); }
public GenericRuleMap(Type genericTypeDefinition, Type[] genericArgumentsTemplate, AnonymousTypeBuilder anonymousTypeBuilder, IModel model) : base(anonymousTypeBuilder, model) { if (!genericTypeDefinition.IsGenericTypeDefinition) { throw new ArgumentException($"Type {genericTypeDefinition.FullName} must be a generic type definition"); } GenericTypeDefinition = genericTypeDefinition; var genericTypeArguments = genericTypeDefinition.GetGenericArguments(); if (genericTypeArguments.Length != genericArgumentsTemplate.Length) { throw new ArgumentException($"Not enough generic arguments placeholders supplied for type {genericTypeDefinition.FullName}, expected {genericTypeArguments.Length}, received {genericArgumentsTemplate.Length}"); } GenericArgumentsTemplate = genericArgumentsTemplate; }
public void Equals_SameFieldValue_ReturnsTrue() { AnonymousTypeBuilder sut = new AnonymousTypeBuilder(); Type t = sut.CreateAnonymousType(new[] { ("Name", typeof(string)) });
public CommentRuleMap(AnonymousTypeBuilder anonymousTypeBuilder, IModel model) : base(anonymousTypeBuilder, model) { }
public void OneTimeSetUp() { // This is needed to get parser to use same anonymous types as those in expected expressions. AnonymousTypeBuilder.ScanAssemblyForExistingAnonymousTypes(GetType().Assembly); }
public Type CreateType(Type[] types, string[] names) { Type orAdd; string str; string str1 = string.Join("|", from x in names select AnonymousTypeBuilder.Escape(x)); if (!this.generatedTypes.TryGetValue(str1, out orAdd)) { lock (this.generatedTypes) { if (!this.generatedTypes.TryGetValue(str1, out orAdd)) { int num = Interlocked.Increment(ref this.Index); str = (names.Length != 0 ? string.Format("<T>AnonymousType{0}`{1}", num, (int)names.Length) : string.Format("<T>AnonymousType{0}", num)); TypeBuilder typeBuilder = this.moduleBuilder.DefineType(str, TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit); typeBuilder.SetCustomAttribute(AnonymousTypeBuilder.compilerGeneratedAttributeBuilder); ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, types); constructorBuilder.SetCustomAttribute(AnonymousTypeBuilder.debuggerHiddenAttributeBuilder); ILGenerator lGenerator = constructorBuilder.GetILGenerator(); lGenerator.Emit(OpCodes.Ldarg_0); lGenerator.Emit(OpCodes.Call, AnonymousTypeBuilder.objectCtor); FieldBuilder[] fieldBuilderArray = new FieldBuilder[(int)names.Length]; for (int i = 0; i < (int)names.Length; i++) { fieldBuilderArray[i] = typeBuilder.DefineField(string.Format("<{0}>i__Field", names[i]), types[i], FieldAttributes.Private | FieldAttributes.InitOnly); fieldBuilderArray[i].SetCustomAttribute(AnonymousTypeBuilder.debuggerBrowsableAttributeBuilder); constructorBuilder.DefineParameter(i + 1, ParameterAttributes.None, names[i]); lGenerator.Emit(OpCodes.Ldarg_0); if (i == 0) { lGenerator.Emit(OpCodes.Ldarg_1); } else if (i == 1) { lGenerator.Emit(OpCodes.Ldarg_2); } else if (i == 2) { lGenerator.Emit(OpCodes.Ldarg_3); } else if (i >= 255) { lGenerator.Emit(OpCodes.Ldarg, (short)(i + 1)); } else { lGenerator.Emit(OpCodes.Ldarg_S, (byte)(i + 1)); } lGenerator.Emit(OpCodes.Stfld, fieldBuilderArray[i]); MethodBuilder methodBuilder = typeBuilder.DefineMethod(string.Format("get_{0}", names[i]), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, CallingConventions.HasThis, types[i], Type.EmptyTypes); ILGenerator lGenerator1 = methodBuilder.GetILGenerator(); lGenerator1.Emit(OpCodes.Ldarg_0); lGenerator1.Emit(OpCodes.Ldfld, fieldBuilderArray[i]); lGenerator1.Emit(OpCodes.Ret); typeBuilder.DefineProperty(names[i], PropertyAttributes.None, CallingConventions.HasThis, types[i], Type.EmptyTypes).SetGetMethod(methodBuilder); } MethodBuilder methodBuilder1 = typeBuilder.DefineMethod("ToString", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(string), Type.EmptyTypes); methodBuilder1.SetCustomAttribute(AnonymousTypeBuilder.debuggerHiddenAttributeBuilder); ILGenerator lGenerator2 = methodBuilder1.GetILGenerator(); lGenerator2.DeclareLocal(typeof(StringBuilder)); lGenerator2.Emit(OpCodes.Newobj, AnonymousTypeBuilder.stringBuilderCtor); lGenerator2.Emit(OpCodes.Stloc_0); lGenerator.Emit(OpCodes.Ret); lGenerator2.Emit(OpCodes.Ldloc_0); lGenerator2.Emit(OpCodes.Ldstr, (names.Length == 0 ? "{ }" : " }")); lGenerator2.Emit(OpCodes.Callvirt, AnonymousTypeBuilder.stringBuilderAppendString); lGenerator2.Emit(OpCodes.Pop); lGenerator2.Emit(OpCodes.Ldloc_0); lGenerator2.Emit(OpCodes.Callvirt, AnonymousTypeBuilder.objectToString); lGenerator2.Emit(OpCodes.Ret); orAdd = typeBuilder.CreateTypeInfo().AsType(); orAdd = this.generatedTypes.GetOrAdd(str1, orAdd); } } } return(orAdd); }
/// <summary> /// Join using relationship /// </summary> /// <param name="outer"></param> /// <param name="inner"></param> /// <param name="relationship"></param> /// <param name="outerSelector"></param> /// <param name="innerSelector"></param> /// <param name="resultSelector"></param> /// <returns></returns> public static IQueryable <TResult> Join <TOuter, TInner, TRelationship, TOuterEndPoint, TInnerEndPoint, TResult>( [NotNull] this IQueryable <TOuter> outer, [NotNull] IEnumerable <TInner> inner, [NotNull] IEnumerable <TRelationship> relationship, [NotNull] Expression <Func <TOuter, TOuterEndPoint> > outerSelector, [NotNull] Expression <Func <TInner, TInnerEndPoint> > innerSelector, Expression <Func <TOuter, TInner, TRelationship, TResult> > resultSelector ) { Check.NotNull(outer, nameof(outer)); Check.NotNull(inner, nameof(inner)); Check.NotNull(outerSelector, nameof(outerSelector)); Check.NotNull(innerSelector, nameof(innerSelector)); Check.NotNull(resultSelector, nameof(resultSelector)); // grab outer and relationship into the first join var startParameters = new ParameterExpression[] { resultSelector.Parameters.ElementAt(0), resultSelector.Parameters.ElementAt(2) }; var startReturnsParameters = startParameters .Select(p => new KeyValuePair <string, Type>(p.Name, p.Type)) .ToList(); var startReturns = AnonymousTypeBuilder.Create(startReturnsParameters); LambdaExpression start = Expression.Lambda( Expression.New( startReturns.GetConstructor( startReturnsParameters .Select(p => p.Value) .ToArray() ), startParameters ), startParameters ); // grab the returns of the first join and inner into the second join var endLambdaParameters = new ParameterExpression[] { Expression.Parameter(startReturns), resultSelector.Parameters.ElementAt(1) }; Expression end = Expression.Lambda( resultSelector.Body, endLambdaParameters ); // replace using relinq outer and relationship parameter expressions var outerMemberExpression = Expression.PropertyOrField( endLambdaParameters.ElementAt(0), resultSelector.Parameters.ElementAt(0).Name ); var relationshipMemberExpression = Expression.PropertyOrField( endLambdaParameters.ElementAt(0), resultSelector.Parameters.ElementAt(2).Name ); end = ReplacingExpressionVisitor.Replace( resultSelector.Parameters.ElementAt(0), outerMemberExpression, end ); end = ReplacingExpressionVisitor.Replace( resultSelector.Parameters.ElementAt(2), relationshipMemberExpression, end ); // construct method calls var startMethodInfo = Join_TOuter_TInner_TKey_TResult_5( typeof(TOuter), typeof(TRelationship), typeof(TOuterEndPoint), startReturns ); var fakeOuterEndpointSelector = Expression.Lambda( outerSelector.Body, new ParameterExpression[] { Expression.Parameter(typeof(TRelationship)) } ); var startExpression = Expression.Call( null, startMethodInfo, outer.Expression, GetSourceExpression(relationship), Expression.Quote(outerSelector), Expression.Quote(fakeOuterEndpointSelector), Expression.Quote(start) ); var endMethodInfo = Join_TOuter_TInner_TKey_TResult_5( startReturns, typeof(TInner), typeof(TInnerEndPoint), typeof(TResult) ); var fakeInnerEndpointSelector = Expression.Lambda( innerSelector.Body, new ParameterExpression[] { Expression.Parameter(startReturns) } ); var wrapped = Expression.Call( null, endMethodInfo, startExpression, GetSourceExpression(inner), Expression.Quote(fakeInnerEndpointSelector), Expression.Quote(innerSelector), Expression.Quote(end) ); return(outer.Provider.CreateQuery <TResult>(wrapped)); }
public void SetUp() { this.propNames = new[] { "Foo", "Bar" }; this.builder = new AnonymousTypeBuilder(this.propNames); }