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 { private static Type ext_type = typeof(IExternalizable); private HashMap all_types = new HashMap(); private HashMap typecls = new HashMap(); private HashMap typeids = new HashMap(); private Log.Logger log = Log.LoggerFactory.GetLogger(typeof(MessageFactoryGenerator).Name); private Type[] null_args = new Type[0]; /// /// 将一个程序集内的所有类符合[MessageType]的类全部注册到编解码器 /// /// 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(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 SyncType() { typecls.Clear(); typeids.Clear(); List typenames = new List(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(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(x); MessageTypeAttribute mtY = PropertyUtil.GetAttribute(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 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(); } } }