view Implab.ServiceHost/Unity/ContainerConfigurationSchema.cs @ 278:6691aff01de1 v3

Implab: added XmlDefaultSeializer (SerializersPool is now obsolete) Implab.ServiceHost: rewritten TypeReference (added support for nested types), stable API
author cin
date Thu, 03 May 2018 09:59:44 +0300
parents 963b17c275be
children f07be402ab02
line wrap: on
line source

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<XmlSerializer> 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<XmlSerializer>(() => 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<T>(string name) where T : AbstractContainerItem {
            RegisterContainerElement(typeof(T), name);
        }

        public ContainerElement LoadFile(string file) {
            using (var reader = XmlReader.Create(file)) {
                return (ContainerElement)Serializer.Deserialize(reader);
            }
        }

        static ContainerConfigurationSchema CreateDefault() {
            var schema = new ContainerConfigurationSchema();

            schema.RegisterContainerElement<RegisterElement>("register");
            schema.RegisterContainerElement<FactoryElement>("factory");
            schema.RegisterContainerElement<SerializedElement>("serialized");
            schema.RegisterContainerElement<ValueElement>("value");
            schema.RegisterContainerElement<IncludeElement>("include");
            schema.RegisterContainerElement<AssemblyElement>("assembly");
            schema.RegisterContainerElement<NamespaceElement>("namespace");

            return schema;
        }


    }
}