/// <summary> /// Initialize from <see cref="XmlElement" />. Can be used to embed cache configuration in larger configuration files /// </summary> /// <param name="doc"> </param> private void LoadFromElement(XmlElement doc) { var persistent = StringFromXpath(doc, "@isPersistent"); IsPersistent = IsYes(persistent); var nodeList = doc.SelectNodes("//connectionPool"); if (nodeList != null) { foreach (XmlNode node in nodeList) { var capacity = StringFromXpath(node, "capacity"); ConnectionPoolCapacity = int.Parse(capacity); var preloaded = StringFromXpath(node, "preloaded"); PreloadedConnections = int.Parse(preloaded); } } //read servers nodeList = doc.SelectNodes("//servers/server"); if (nodeList != null) { foreach (XmlNode node in nodeList) { var cfg = new ServerConfig(); var port = StringFromXpath(node, "port"); cfg.Port = int.Parse(port); var host = StringFromXpath(node, "host"); cfg.Host = host; var weight = StringFromXpath(node, "weight"); Servers.Add(cfg); } } //read converters nodeList = doc.SelectNodes("//keyConverters/converter"); if (nodeList != null) { foreach (XmlNode node in nodeList) { var converterTypeName = StringFromXpath(node, "@fullName"); var converterType = Type.GetType(converterTypeName); if (converterType == null) { throw new CacheException( $"Can not instantiate a key converter for type {converterTypeName}"); } if (!(Activator.CreateInstance(converterType) is IKeyConverter converter)) { throw new CacheException( $"Can not instantiate a key converter for type {converterTypeName}"); } } } //type descriptions nodeList = doc.SelectNodes("//typeDescriptions/type"); if (nodeList != null) { foreach (XmlNode node in nodeList) { var typeDescription = new TypeDescriptionConfig(); var typeName = StringFromXpath(node, "@fullName"); if (string.IsNullOrEmpty(typeName)) { throw new CacheException("Missing fullName attribute on a type description"); } var assemblyName = StringFromXpath(node, "@assembly"); if (string.IsNullOrEmpty(assemblyName)) { throw new CacheException("Missing assembly attribute on a type description"); } var useCompression = StringFromXpath(node, "@useCompression"); typeDescription.UseCompression = IsYes(useCompression); typeDescription.FullTypeName = typeName; typeDescription.AssemblyName = assemblyName; var propertyNodes = node.SelectNodes("property"); if (propertyNodes != null) { foreach (XmlNode propertyNode in propertyNodes) { var propertyName = StringFromXpath(propertyNode, "@name"); var propertyType = StringFromXpath(propertyNode, "@keyType"); KeyType keyType; switch (propertyType.ToUpper()) { case "PRIMARY": keyType = KeyType.Primary; break; case "UNIQUE": keyType = KeyType.Unique; break; case "INDEX": keyType = KeyType.ScalarIndex; break; case "LIST": keyType = KeyType.ListIndex; break; default: throw new CacheException( $"Unknown key type {propertyType} for property{propertyName}"); } var keyDataType = StringFromXpath(propertyNode, "@dataType"); KeyDataType dataType; switch (keyDataType.ToUpper()) { case "INT": case "INTEGER": dataType = KeyDataType.IntKey; break; case "STRING": dataType = KeyDataType.StringKey; break; default: throw new CacheException( $"Unknown key data type {keyDataType} for property{propertyName}"); } var orderedIndex = StringFromXpath(propertyNode, "@ordered"); var ordered = orderedIndex.ToUpper() == "TRUE"; var fullText = StringFromXpath(propertyNode, "@fullTextIndexed"); var fullTextIndexed = fullText.ToUpper() == "TRUE"; typeDescription.Add(propertyName, keyType, dataType, ordered, fullTextIndexed); } } TypeDescriptions.Add(typeName, typeDescription); } } }