Exemplo n.º 1
0
        // make filter fake object
        private Type CreateFakeFilterObjectType(string name, Type t, ModuleBuilder mb = null)
        {
            // make first type from all fields
            TypeBuilder ntb = mb.DefineType(name + "_t", TypeAttributes.Public);

            // fields
            IEnumerable <FieldInfo> fields = t.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

            fields.Where(f => f.FieldType.IsSubclassOfRawGeneric(typeof(FilterField <>)))
            .Select(f => {
                // we need handle correctly name of field cause private filed will lowercased first letter just
                // after first _
                // so we have to attempt to find property which need to match
                String tmpName  = f.Name.Substring(f.Name.IndexOf('_') + 1);
                PropertyInfo pi = t.GetProperty(tmpName, BindingFlags.Public | BindingFlags.Instance);
                if (ReferenceEquals(null, pi))
                {
                    // try with uppercased first letter
                    pi = t.GetProperty(tmpName.UppercaseFirst(), BindingFlags.Public | BindingFlags.Instance);
                }
                tmpName = ReferenceEquals(null, pi) ? tmpName : pi.Name;
                return(new fake_filter_field()
                {
                    name = tmpName,  //  f.Name.Substring(f.Name.IndexOf('_') + 1),
                    // filter field is template so take its first generic argument and check it if it is generic again
                    type = f.FieldType.GenericTypeArguments[0].IsGenericType ?
                           // nullable<>
                           f.FieldType.GenericTypeArguments[0].GenericTypeArguments[0] :
                           // direct type
                           f.FieldType.GenericTypeArguments[0]
                });
            }).ToList()
            .ForEach(c => { ReflectionHelper.AddProperty(ntb, c.name, c.type); });

            // nested collections
            fields.Where(f => f.FieldType.IsSubclassOfRawGeneric(typeof(FilterObjectsCollection <>)))
            .Select(f => {
                // we need handle correctly name of field cause private filed will lowercased first letter just
                // after first _
                // so we have to attempt to find property which need to match
                String tmpName  = f.Name.Substring(f.Name.IndexOf('_') + 1);
                PropertyInfo pi = t.GetProperty(tmpName, BindingFlags.Public | BindingFlags.Instance);
                if (ReferenceEquals(null, pi))
                {
                    // try with uppercased first letter
                    pi = t.GetProperty(tmpName.UppercaseFirst(), BindingFlags.Public | BindingFlags.Instance);
                }
                tmpName = ReferenceEquals(null, pi) ? tmpName : pi.Name;
                return(new fake_filter_field()
                {
                    name = tmpName,
                    type = f.FieldType.GenericTypeArguments[0]
                });
            }).ToList()
            .ForEach(c =>
            {
                ReflectionHelper.AddProperty(
                    ntb,
                    c.name,
                    typeof(List <>).MakeGenericType(new Type[] { CreateFakeFilterObjectType(c.name, c.type, mb) })
                    );
            });

            // nested objects
            fields.Where(f => f.FieldType.IsSubclassOfRawGeneric(typeof(FilterObjectbase)))
            .Select(f => {
                // we need handle correctly name of field cause private filed will lowercased first letter just
                // after first _
                // so we have to attempt to find property which need to match
                String tmpName  = f.Name.Substring(f.Name.IndexOf('_') + 1);
                PropertyInfo pi = t.GetProperty(tmpName, BindingFlags.Public | BindingFlags.Instance);
                if (ReferenceEquals(null, pi))
                {
                    // try with uppercased first letter
                    pi = t.GetProperty(tmpName.UppercaseFirst(), BindingFlags.Public | BindingFlags.Instance);
                }
                tmpName = ReferenceEquals(null, pi) ? tmpName : pi.Name;
                return(new fake_filter_field()
                {
                    name = tmpName,
                    type = f.FieldType
                });
            }).ToList()
            .ForEach(c =>
            {
                ReflectionHelper.AddProperty(
                    ntb,
                    c.name,
                    CreateFakeFilterObjectType(c.name, c.type, mb)
                    );
            });

            // now make property
            return(ntb.CreateType());
        }