using Ant.Common; using Ant.Core; using Ant.Core.Emit; using Ant.Query.Mapping; using Ant.Utility; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Reflection; using System.Text; namespace Ant.Mapper { public class EntityMemberMapper { Dictionary _mappingMemberMRMContainer; Dictionary> _navigationMemberSetters; EntityMemberMapper(Type t) { this.Type = t; this.Init(); } void Init() { Type t = this.Type; var members = t.GetMembers(BindingFlags.Public | BindingFlags.Instance); Dictionary mappingMemberMRMContainer = new Dictionary(); Dictionary> navigationMemberSetters = new Dictionary>(); foreach (var member in members) { Type memberType = null; PropertyInfo prop = null; FieldInfo field = null; if ((prop = member as PropertyInfo) != null) { if (prop.GetSetMethod() == null) continue;//对于没有公共的 setter 直接跳过 memberType = prop.PropertyType; } else if ((field = member as FieldInfo) != null) { memberType = field.FieldType; } else continue;//只支持公共属性和字段 if (AntUtils.IsMapType(memberType)) { IMRM mrm = MRMHelper.CreateMRM(member); mappingMemberMRMContainer.Add(member, mrm); } else { if (prop != null) { Action valueSetter = DelegateGenerator.CreateValueSetter(prop); navigationMemberSetters.Add(member, valueSetter); } else if (field != null) { Action valueSetter = DelegateGenerator.CreateValueSetter(field); navigationMemberSetters.Add(member, valueSetter); } else continue; continue; } } this._mappingMemberMRMContainer = AntUtils.Clone(mappingMemberMRMContainer); this._navigationMemberSetters = AntUtils.Clone(navigationMemberSetters); } public Type Type { get; private set; } public IMRM GetMemberMapper(MemberInfo memberInfo) { IMRM mapper = null; this._mappingMemberMRMContainer.TryGetValue(memberInfo, out mapper); return mapper; } public Action GetNavigationMemberSetter(MemberInfo memberInfo) { Action valueSetter = null; this._navigationMemberSetters.TryGetValue(memberInfo, out valueSetter); return valueSetter; } static readonly System.Collections.Concurrent.ConcurrentDictionary InstanceCache = new System.Collections.Concurrent.ConcurrentDictionary(); public static EntityMemberMapper GetInstance(Type type) { EntityMemberMapper instance; if (!InstanceCache.TryGetValue(type, out instance)) { lock (type) { if (!InstanceCache.TryGetValue(type, out instance)) { instance = new EntityMemberMapper(type); InstanceCache.GetOrAdd(type, instance); } } } return instance; } } }