internal TypeSchema(IArea area, IConfigSectionNode cfg) { m_Area = area.NonNull(nameof(area)); if (!cfg.NonEmpty(nameof(cfg)).IsSameName(CONFIG_SCHEMA_SECTION)) { cfg = cfg[CONFIG_SCHEMA_SECTION]; } cfg.NonEmpty(nameof(CONFIG_SCHEMA_SECTION)); m_Assemblies = new Dictionary <string, BuildInformation>(StringComparer.OrdinalIgnoreCase); m_ObjectTypes = new Dictionary <string, Type>(StringComparer.OrdinalIgnoreCase); m_QueryTypes = new Dictionary <string, List <Type> >(StringComparer.OrdinalIgnoreCase); try { foreach (var node in cfg.ChildrenNamed(CONFIG_ASSEMBLY_SECTION)) { var fn = node.ValOf(CONFIG_FILE_ATTR).NonBlank("{0}/${1}".Args(node.RootPath, CONFIG_FILE_ATTR)); var asm = Assembly.LoadFrom(fn); var nsPat = node.ValOf(CONFIG_NS_PATTERN_ATTR).Default("*"); load(asm, nsPat); } //Computer version digest on SORTED assembly Build infos //the operation is deferred after all assemblies finished loading m_Version = 0; foreach (var entry in m_Assemblies.OrderBy(e => e.Key)) //(deterministic order) based on Assembly FQN { m_Version ^= ShardKey.ForString(entry.Value.Content); //compute version digest hash based on the BuildInfo } } catch (Exception error) { throw new ConfigException("Bad config of {0}: {1}".Args(nameof(TypeSchema), error.ToMessageWithType()), error); } }