1using System.Diagnostics;
2using System.Reflection;
8internal class DataContextBuilder<DB> where DB : DataContext
10 public DB Build(
Client client)
12 var dbType = typeof(DB);
13 const BindingFlags 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);
27 var colImpls =
new Dictionary<Type, DataContext.ICollection>();
28 foreach (var ty
in colTypes)
30 colImpls[ty] = (DataContext.ICollection)Activator.CreateInstance(ty)!;
31 var nameAttr = ty.GetCustomAttribute<DataContext.NameAttribute>();
32 var colName = nameAttr?.Name ?? ty.Name;
35 var db = (DB)Activator.CreateInstance(dbType)!;
40 private static bool IsColType(Type ty) =>
41 ty.GetInterfaces().Any(iface => iface == typeof(DataContext.ICollection));
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)}");
97 private static Type? GetColBase(Type ty) => ty.GetGenInst(typeof(DataContext.Collection<>));
99 private static Type GetDocType(Type ty)
101 var col = GetColBase(ty);
102 Debug.Assert(col is not
null);
103 return col.GetGenericArguments()[0];
Represents a client for interacting with a Fauna.
A class representing the mapping context to be used during serialization and deserialization.