using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Xml; using System.Xml.Serialization; using Implab.Components; namespace Implab.ServiceHost.Unity { public class ContainerConfigurationSchema { public static ContainerConfigurationSchema Default { get; private set; } = CreateDefault(); readonly LazyAndWeak m_seralizer; readonly XmlAttributeOverrides m_overrides = new XmlAttributeOverrides(); readonly XmlAttributes m_containerItems = new XmlAttributes(); public XmlSerializer Serializer { get { return m_seralizer.Value; } } public ContainerConfigurationSchema() { m_overrides.Add(typeof(ContainerElement), nameof(ContainerElement.Items), m_containerItems); m_seralizer = new LazyAndWeak(() => new XmlSerializer(typeof(ContainerElement), m_overrides)); } public void RegisterContainerElement(Type type, string name) { Safe.ArgumentNotNull(type, nameof(type)); Safe.ArgumentNotEmpty(name, nameof(name)); if(!type.IsSubclassOf(typeof(AbstractContainerItem))) throw new Exception($"RegisterContainerElement '{name}': {type} must be subclass of {typeof(AbstractContainerItem)}"); m_containerItems.XmlElements.Add( new XmlElementAttribute(name, type) ); } public void RegisterContainerElement(string name) where T : AbstractContainerItem { RegisterContainerElement(typeof(T), name); } public ContainerElement LoadConfig(string uri) { using (var reader = XmlReader.Create(uri)) { return (ContainerElement)Serializer.Deserialize(reader); } } static ContainerConfigurationSchema CreateDefault() { var schema = new ContainerConfigurationSchema(); schema.RegisterContainerElement("register"); schema.RegisterContainerElement("factory"); schema.RegisterContainerElement("serialized"); schema.RegisterContainerElement("value"); schema.RegisterContainerElement("include"); schema.RegisterContainerElement("assembly"); schema.RegisterContainerElement("namespace"); return schema; } } }