Пример #1
0
        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;
        }
Пример #5
0
        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));
        }
Пример #7
0
        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 });
        }
Пример #8
0
 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>();
 }
Пример #9
0
 public UserRuleMap(AnonymousTypeBuilder anonymousTypeBuilder, IModel model) : base(anonymousTypeBuilder, model)
 {
 }
Пример #10
0
        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());
        }
Пример #11
0
        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)) });
Пример #13
0
 public CommentRuleMap(AnonymousTypeBuilder anonymousTypeBuilder, IModel model) : base(anonymousTypeBuilder, model)
 {
 }
Пример #14
0
 public void OneTimeSetUp()
 {
     // This is needed to get parser to use same anonymous types as those in expected expressions.
     AnonymousTypeBuilder.ScanAssemblyForExistingAnonymousTypes(GetType().Assembly);
 }
Пример #15
0
    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));
        }
Пример #17
0
 public void SetUp()
 {
     this.propNames = new[] { "Foo", "Bar" };
     this.builder   = new AnonymousTypeBuilder(this.propNames);
 }