// 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()); }