@@ -15,21 +15,35 @@ public static class SchemaHelper
1515 //private static readonly ConcurrentDictionary<string, List<StoreSchema>> _databaseSchemasCache = new();
1616 //private static bool _schemasScanned = false;
1717 //private static readonly object _lock = new();
18- internal static readonly ConcurrentDictionary < string , Type > _schemaCache = new ( ) ;
18+ internal static readonly ConcurrentDictionary < Type , IMagicTableBase ? > _schemaCache = new ( ) ;
1919
2020 internal static void EnsureSchemaIsCached ( Type type )
2121 {
22- string typeKey = type . FullName ! ;
23-
24- _schemaCache . GetOrAdd ( typeKey , _ =>
22+ _schemaCache . GetOrAdd ( type , _ =>
2523 {
26- if ( ! typeof ( IMagicTableBase ) . IsAssignableFrom ( type ) )
27- throw new InvalidOperationException ( $ "Type { type . Name } does not implement IMagicTableBase." ) ;
28-
29- return type ; // Cache the type itself
24+ // Check if the type implements IMagicTableBase
25+ return typeof ( IMagicTableBase ) . IsAssignableFrom ( type )
26+ ? ( Activator . CreateInstance ( type ) as IMagicTableBase ) // Store the instance if valid
27+ : null ; // Store null if it doesn’t implement IMagicTableBase
3028 } ) ;
3129 }
3230
31+
32+ public static bool ImplementsIMagicTable ( Type type )
33+ {
34+ return type . GetInterfaces ( ) . Any ( i => i . IsGenericType
35+ && i . GetGenericTypeDefinition ( ) == typeof ( IMagicTable < > ) ) ;
36+ }
37+
38+ public static List < Type > ? GetAllMagicTables ( )
39+ {
40+ var assemblies = AppDomain . CurrentDomain . GetAssemblies ( ) ;
41+ return assemblies
42+ . SelectMany ( a => a . GetTypes ( ) )
43+ . Where ( t => t . IsClass && ! t . IsAbstract && SchemaHelper . ImplementsIMagicTable ( t ) )
44+ . ToList ( ) ;
45+ }
46+
3347 private static readonly ConcurrentDictionary < Type , string > _tableNameCache = new ( ) ;
3448 private static readonly ConcurrentDictionary < Type , string > _databaseNameCache = new ( ) ;
3549
@@ -143,16 +157,24 @@ public static StoreSchema GetStoreSchema(Type type)
143157 PropertyMappingCache . EnsureTypeIsCached ( type ) ;
144158 EnsureSchemaIsCached ( type ) ;
145159
146- if ( ! _schemaCache . TryGetValue ( type . FullName ! , out var cachedType ) )
147- throw new InvalidOperationException ( $ "Type { type . Name } is not cached and does not implement IMagicTableBase.") ;
160+ // Retrieve the cached entry
161+ if ( ! _schemaCache . TryGetValue ( type , out var instance ) )
162+ {
163+ throw new InvalidOperationException ( $ "Type { type . Name } is not cached.") ;
164+ }
148165
149- var instance = Activator . CreateInstance ( cachedType ) as IMagicTableBase ;
166+ // Ensure the type actually implements IMagicTableBase
150167 if ( instance == null )
151- throw new InvalidOperationException ( $ "Failed to create an instance of { cachedType . Name } .") ;
168+ {
169+ throw new InvalidOperationException ( $ "Type { type . Name } does not implement IMagicTableBase and cannot be used as a Magic Table.") ;
170+ }
152171
172+ // Retrieve table name
153173 var tableName = instance . GetTableName ( ) ;
154174 if ( string . IsNullOrWhiteSpace ( tableName ) )
155- throw new InvalidOperationException ( $ "Type { cachedType . Name } returned an invalid table name.") ;
175+ {
176+ throw new InvalidOperationException ( $ "Type { type . Name } returned an invalid table name.") ;
177+ }
156178
157179 var schema = new StoreSchema
158180 {
@@ -165,7 +187,9 @@ public static StoreSchema GetStoreSchema(Type type)
165187 . FirstOrDefault ( prop => PropertyMappingCache . GetPropertyEntry ( prop , type ) . PrimaryKey ) ;
166188
167189 if ( primaryKeyProperty == null )
190+ {
168191 throw new InvalidOperationException ( $ "The entity { type . Name } does not have a primary key attribute.") ;
192+ }
169193
170194 schema . PrimaryKey = PropertyMappingCache . GetJsPropertyName ( primaryKeyProperty , type ) ;
171195
@@ -183,5 +207,6 @@ public static StoreSchema GetStoreSchema(Type type)
183207
184208 return schema ;
185209 }
210+
186211 }
187212}
0 commit comments