--- trunk/libxmltv/Core/XMLTV.cs 2013/03/08 05:20:12 49 +++ trunk/libxmltv/Core/XMLTV.cs 2013/03/08 12:05:33 56 @@ -4,6 +4,9 @@ using System.Text; using libxmltv.Interfaces; using System.ComponentModel; +using System.IO; +using System.Reflection; +using System.Globalization; namespace libxmltv.Core { @@ -12,15 +15,146 @@ /// public static class XMLTV { - static XMLTV() { xmltv_logger.Initialize(); } + static XMLTV() + { + xmltv_logger.Initialize(); + if (instance == null) + { + instance = new XMLTV(); + } + } - private static XMLTVRuntimeInstance instance; - public static IXMLTVRuntimeInstance GetInstance() { return InternalGetInstance(); } - internal static XMLTVRuntimeInstance InternalGetInstance() { return instance; } - public static void CreateInstance(string xml_file) { CreateInstance(xml_file, null); } - public static void CreateInstance(string xml_file, EventHandler t) { instance = new XMLTVRuntimeInstance(xml_file, t); } - public static IXMLTVSerializer GetSerializer() {return InternalGetInstance().Serializer; } + static IXMLTV instance; + public static IXMLTVRuntimeInstance GetInstance() { return instance.GetInstance(); } + public static void CreateInstance(params object[] args) { instance = new XMLTV(args); } + + public static void CreateFromInstance(object raw_instance, EventHandler handler) + { + instance = new XMLTV(raw_instance,handler); + if (OnInstanceCreated != null) + { + OnInstanceCreated.Invoke(null, new EventArgs()); + } + } + + #region IXMLTVSerializer members + public static bool Serialize(string file) { return instance.Serialize(file); } + public static bool Serialize(Stream stream) { return instance.Serialize(stream); } + public static IXMLTVRuntimeInstance DeSerialize(string file, out bool status) { return instance.DeSerialize(file, out status); } + public static IXMLTVRuntimeInstance DeSerialize(Stream stream, out bool status) { return instance.DeSerialize(stream, out status); } + #endregion + + public static void DestroyInstance() { instance.DestroyInstance(); } + + public static EventHandler OnInstanceCreated + { + get { return instance.OnInstanceCreated; } + set { instance.OnInstanceCreated = value; } + } + } + + internal class XMLTV : IDestroyInstance, IXMLTV where CLASS : class,INTERFACE,new() + { + public XMLTV() + { + instance = new CLASS(); + } + public XMLTV(object raw_instance, EventHandler handler) + { + instance = (CLASS)Convert.ChangeType(raw_instance, typeof(CLASS)); + if (instance != null) + { + IRuntimeInstanceLoader loader = (instance as IRuntimeInstanceLoader); + if (loader != null) + { + SetOnInstanceCreated(handler); + instance = loader.LoadFromInstance(instance); + } + } + } + public XMLTV(params object[] args) + { + + BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; + CultureInfo culture = CultureInfo.CurrentCulture; + try + { + object raw_instance = Activator.CreateInstance(typeof(CLASS), flags, null, args, culture); + instance = (CLASS)Convert.ChangeType(raw_instance, typeof(CLASS)); + } + catch (Exception ex) + { + xmltv_logger.Error.WriteLine(ex.ToString()); + + StringBuilder parameter_builder = new StringBuilder(); + foreach (object arg in args) + { + Type type = arg.GetType(); + parameter_builder.AppendFormat("({0}), ", type.FullName); + } + + string type_parameters = parameter_builder.ToString().TrimEnd(new char[] { ',', ' ' }); + throw new Exception(string.Format("Unable to create instance of: '{0}' with parameters: '{1}'", typeof(CLASS).Name, type_parameters), ex); + } + } + + private CLASS instance; + #region IXMLTV members + public IXMLTVSerializer CreateSerializer() + { + // we must serialize on the CLASS type, using the INTERFACE type is syntatically incorrect + ISerializer class_serializer = (instance as ISerializer); + if (class_serializer != null) + { + return class_serializer.Serializer; + } + else + { + return new XMLTVSerializer(instance); + } + } + public INTERFACE GetInstance() + { + return (INTERFACE)instance; + } + #endregion + + #region IXMLTVSerializer members + public bool Serialize(string file) { return CreateSerializer().Serialize(file); } + public bool Serialize(Stream stream) { return CreateSerializer().Serialize(stream); } + public INTERFACE DeSerialize(string file, out bool status) { return CreateSerializer().DeSerialize(file, out status); } + public INTERFACE DeSerialize(Stream stream, out bool status) { return CreateSerializer().DeSerialize(stream, out status); } + #endregion + public void DestroyInstance() + { + IDestroyInstance destoyer = (instance as IDestroyInstance); + if (destoyer != null) + { + destoyer.DestroyInstance(); + } + else + { + xmltv_logger.Error.WriteLine("Unable to call DestroyInstance() on type: '{0}'", instance.GetType().Name); + } + } + private void SetOnInstanceCreated(EventHandler event_instance) + { + ISetCreatedInstanceEvent setter = (instance as ISetCreatedInstanceEvent); + if (setter != null) { setter.SetOnInstanceCreated(event_instance); } + } + private EventHandler GetOnInstanceCreated() + { + IGetCreatedInstanceEvent getter = (instance as IGetCreatedInstanceEvent); + if (getter != null) { return getter.GetOnInstanceCreated(); } + return null; + } + public EventHandler OnInstanceCreated + { + get { return GetOnInstanceCreated(); } + set { SetOnInstanceCreated(value); } + } } + }