using System; using System.Collections.Generic; using System.Reflection; using System.Xml; using System.Globalization; using CommonLang; using CommonLang.IO; using CommonLang.IO.Attribute; using CommonLang.Property; using CommonLang.Protocol; using System.Text; namespace CommonLang.Protocol { public class MessageFactoryGenerator : IExternalizableFactory, IComparer<Type> { private static Type ext_type = typeof(IExternalizable); private HashMap<Type, Type> all_types = new HashMap<Type, Type>(); private HashMap<int, Type> typecls = new HashMap<int, Type>(); private HashMap<Type, int> typeids = new HashMap<Type, int>(); private Log.Logger log = Log.LoggerFactory.GetLogger(typeof(MessageFactoryGenerator).Name); private Type[] null_args = new Type[0]; /// <summary> /// 将一个程序集内的所有类符合[MessageType]的类全部注册到编解码器 /// </summary> /// <param name="assembly"></param> public void RegistAssembly(params Assembly[] assembly) { foreach (Assembly asm in assembly) { Type[] types = null; try { //log.Info("Get Assembly Types : " + asm.FullName); types = asm.GetTypes(); } catch (Exception err) { log.InfoFormat("Get Types Error : {1}\n {0}", err.Message, asm.FullName); continue; } try { foreach (var type in types) { if (ext_type.IsAssignableFrom(type)) { MessageTypeAttribute msgID = PropertyUtil.GetAttribute<MessageTypeAttribute>(type); if (msgID != null) { if (type.GetConstructor(null_args) == null) { log.ErrorFormat("No default null arguments constructor : {0}\n {1}();", type.FullName, type.Name); } else { all_types.TryAdd(type, type); } } } } } catch (Exception err) { log.Error(err.Message, err); } } SyncType(); } private List<Type> SyncType() { typecls.Clear(); typeids.Clear(); List<Type> typenames = new List<Type>(all_types.Count); foreach (Type type in all_types.Values) { typenames.Add(type); } typenames.Sort(this); for (uint i = 0; i < typenames.Count; i++) { Type type = typenames[(int)i]; MessageTypeAttribute msgID = PropertyUtil.GetAttribute<MessageTypeAttribute>(type); int id = msgID.MessageTypeID; if (id == 0) { id = (int)((i | 0x80000000L) & 0xFFFFFFFF); } if (typecls.ContainsKey(id)) { Type ot = typecls[id]; throw new Exception(string.Format( "Duplicate Type : id = 0x{0} with \"{1}\" - \"{2}\"", id.ToString("X"), type.FullName, ot.FullName)); } typecls.Put(id, type); typeids.Put(type, id); } return typenames; } public int Compare(Type x, Type y) { MessageTypeAttribute mtX = PropertyUtil.GetAttribute<MessageTypeAttribute>(x); MessageTypeAttribute mtY = PropertyUtil.GetAttribute<MessageTypeAttribute>(y); if (mtX != null && mtY != null) { return mtX.MessageTypeID - mtY.MessageTypeID; } if (mtX != null) { return 1; } if (mtY != null) { return -1; } return x.FullName.CompareTo(y.FullName); } public int GetTypeID(Type type) { return typeids.Get(type); } public Type GetType(int id) { return typecls.Get(id); } public string ListAll(string prefix = "") { StringBuilder sb = new StringBuilder(); List<Type> types = SyncType(); foreach (Type type in types) { int id = typeids[type]; object msg = ReflectionUtil.CreateInstance(type); sb.AppendLine(prefix + string.Format("0x{0:X8}", id) + " - " + msg.GetType().FullName); } return sb.ToString(); } } }