internal protected virtual Table Include(Type type, PropertyRoute route) { if (schema.Tables.TryGetValue(type, out Table result)) { return(result); } using (HeavyProfiler.LogNoStackTrace("Include", () => type.TypeName())) { if (type.IsAbstract) { throw new InvalidOperationException(route?.Let(r => "Error on field {0}: ".FormatWith(r)) + "Impossible to include in the Schema the type {0} because is abstract".FormatWith(type)); } if (!Reflector.IsEntity(type)) { throw new InvalidOperationException(route?.Let(r => "Error on field {0}: ".FormatWith(r)) + "Impossible to include in the Schema the type {0} because is not and Entity".FormatWith(type)); } foreach (var t in type.Follow(a => a.BaseType)) { if (!t.IsSerializable) { throw new InvalidOperationException("Type {0} is not marked as serializable".FormatWith(t.TypeName())); } } string name = schema.Settings.desambiguatedNames?.TryGetC(type) ?? Reflector.CleanTypeName(EnumEntity.Extract(type) ?? type); if (schema.NameToType.ContainsKey(name)) { throw new InvalidOperationException(route?.Let(r => "Error on field {0}: ".FormatWith(r)) + "Two types have the same cleanName, desambiguate using Schema.Current.Settings.Desambiguate method: \r\n {0}\r\n {1}".FormatWith(schema.NameToType[name].FullName, type.FullName)); } try { result = new Table(type); schema.Tables.Add(type, result); schema.NameToType[name] = type; schema.TypeToName[type] = name; Complete(result); return(result); } catch (Exception) //Avoid half-cooked tables { schema.Tables.Remove(type); schema.NameToType.Remove(name); schema.TypeToName.Remove(type); throw; } } }
private static string?ErrorIncluding(PropertyRoute?route) { return(route?.Let(r => $"Error including {r}: ")); }