using System; using System.Collections.Generic; using ICD.Common.Properties; using ICD.Common.Utils.Attributes; namespace ICD.Common.Utils.Xml { [MeansImplicitUse] [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] public sealed class XmlConverterAttribute : AbstractIcdAttribute { private static readonly Dictionary s_InstanceTypeToConverter; private static readonly Dictionary s_ConverterTypeToConverter; private readonly Type m_ConverterType; /// /// Gets the converter type. /// public Type ConverterType { get { return m_ConverterType; } } /// /// Static constructor. /// static XmlConverterAttribute() { s_InstanceTypeToConverter = new Dictionary(); s_ConverterTypeToConverter = new Dictionary(); } /// /// Constructor. /// /// public XmlConverterAttribute(Type converterType) { m_ConverterType = converterType; } /// /// Gets the XML converter for the given instance. /// /// /// public static IXmlConverter GetConverterForInstance(object value) { return value == null ? DefaultXmlConverter.Instance(typeof(object)) : GetConverterForType(value.GetType()); } /// /// Gets the XML converter for the given type. /// /// /// public static IXmlConverter GetConverterForType(Type type) { if (type == null) throw new ArgumentNullException("type"); IXmlConverter converter; if (!s_InstanceTypeToConverter.TryGetValue(type, out converter)) { XmlConverterAttribute attribute = AttributeUtils.GetClassAttribute(type); Type converterType = attribute == null ? null : attribute.ConverterType; converter = converterType == null ? DefaultXmlConverter.Instance(type) : LazyLoadConverter(converterType); s_InstanceTypeToConverter[type] = converter; } return converter; } /// /// Lazy-loads the converter of the given type. /// /// /// private static IXmlConverter LazyLoadConverter(Type converterType) { if (converterType == null) throw new ArgumentNullException("converterType"); IXmlConverter converter; if (!s_ConverterTypeToConverter.TryGetValue(converterType, out converter)) { converter = ReflectionUtils.CreateInstance(converterType) as IXmlConverter; s_ConverterTypeToConverter[converterType] = converter; } return converter; } } }