8internal class DataContextBuilder<DB> where DB :
DataContext
10 public DB Build(
Client client)
12 var dbType = typeof(DB);
13 var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
14 var colTypes = dbType.GetNestedTypes(flags).Where(IsColType).ToList();
15 var colProps = dbType.GetProperties(flags).Where(IsColProp).ToList();
17 foreach (var ty
in colTypes)
22 foreach (var p
in colProps)
24 ValidateColProp(colTypes, p);
28 foreach (var ty
in colTypes)
32 var colName = nameAttr?.Name ?? ty.Name;
35 var db = (DB)Activator.CreateInstance(dbType)!;
40 private static bool IsColType(Type ty) =>
43 private static void ValidateColType(Type ty)
45 var isGeneric = ty.IsGenericType;
46 var colDef = GetColBase(ty);
48 var errors =
new List<string>();
50 if (isGeneric) errors.Add(
"Cannot be generic.");
51 if (colDef is
null) errors.Add(
"Must inherit Collection<>.");
55 throw new InvalidOperationException(
56 $
"Invalid collection type: {string.Join(" ", errors)}");
60 private static bool IsColProp(PropertyInfo prop)
62 var getter = prop.GetGetMethod();
64 if (getter is
null)
return false;
65 if (getter.IsStatic)
return false;
67 var retType = getter.ReturnType;
68 if (!IsColType(retType))
return false;
73 private static void ValidateColProp(List<Type> colTypes, PropertyInfo prop)
75 var nullCtx =
new NullabilityInfoContext();
76 var nullInfo = nullCtx.Create(prop);
77 var getter = prop.GetGetMethod()!;
78 var retType = getter.ReturnType;
80 var returnsValidColType = colTypes.Contains(retType);
81 var isNullable = nullInfo.ReadState is NullabilityState.Nullable;
83 var errors =
new List<string>();
85 if (!returnsValidColType) errors.Add(
"Must return a nested collection type.");
86 if (isNullable) errors.Add(
"Cannot be nullable.");
90 throw new InvalidOperationException(
91 $
"Invalid collection property: {string.Join(" ", errors)}");
99 private static Type GetDocType(Type ty)
101 var col = GetColBase(ty);
102 Debug.Assert(col is not
null);
103 return col.GetGenericArguments()[0];