using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Web.UI.WebControls; namespace DymWebForm.Aspx { internal static class FormFieldBase { public static Func GenerateGetterFunc(PropertyInfo pi) { //动态构建lambda表达式, 性能应该杠杠的了 乂D //p=> (object)p. var expParam = Expression.Parameter(typeof(T), "p"); var mma = Expression.MakeMemberAccess( expParam , pi ); var mmac = Expression.Convert(mma, typeof(object)); var exp = Expression.Lambda>(mmac, expParam); return exp.Compile(); } public static Action GenerateSetterAction(PropertyInfo pi) { //动态构建lambda表达式, 性能应该杠杠的了 乂D //p=> p.=(pi.PropertyType)v var expParamP = Expression.Parameter(typeof(T), "p"); var expParamV = Expression.Parameter(typeof(object), "v"); var expParamVc = Expression.Convert(expParamV, pi.PropertyType); var mma = Expression.Call( expParamP , pi.GetSetMethod() , expParamVc ); var exp = Expression.Lambda>(mma, expParamP, expParamV); return exp.Compile(); } } internal class FormField { //inst public PropertyInfo PropertyInfo { get; private set; } //prop public Func GetValue { get; private set; } public Action SetValue { get; private set; } //feature public bool IsPK { get; private set; } public bool IsFK { get; private set; } public Type FKParentType { get; private set; } public bool IsFKDisplay { get; private set; } public int DisplayOrder { get; private set; } public string FieldName { get; private set; } public string DisplayName { get; private set; } public Type DataType { get; private set; } public bool AllowNull { get; private set; } public string ControlID { get; private set; } public bool HasDefaultValueGenerator { get; private set; } public Func GenerateDefaultValue { get; private set; } public Type ValidationType { get; private set; } //ctor public FormField(PropertyInfo pi) { PropertyInfo = pi; var pia = pi; if (pi.DeclaringType.IsDefined(typeof (DWFMetaAttribute), true)) { var mt = ((DWFMetaAttribute) pi.DeclaringType.GetCustomAttributes(typeof (DWFMetaAttribute), true)[0]) .Type; var mp = mt.GetProperty(pi.Name); if (mp != null) pia = mp; } GetValue = FormFieldBase.GenerateGetterFunc(PropertyInfo); SetValue = FormFieldBase.GenerateSetterAction(PropertyInfo); DataType = pi.PropertyType; IsPK = pia.HasAttribute(); IsFK = pia.HasAttribute(); IsFKDisplay = pia.HasAttribute(); HasDefaultValueGenerator = pia.HasAttribute(true); AllowNull = DataType.IsGenericType && DataType.GetGenericTypeDefinition() == typeof (Nullable<>) || pia.HasAttribute(); ValidationType = pia.HasAttribute() ? pia.GetCustomAttributes(typeof (DWFValidationTypeAttribute), true) .Select(p => ((DWFValidationTypeAttribute) p).ValidationType) .First() : null; if (IsFK) FKParentType = pia .GetCustomAttributes(typeof (DWFFKAttribute), true) .Select(p => ((DWFFKAttribute) p).ParentType) .FirstOrDefault(); if (HasDefaultValueGenerator) GenerateDefaultValue = ((DWFDefaultValueGeneratorAttribute) pia.GetCustomAttributes(typeof (DWFDefaultValueGeneratorAttribute), true).First()) .GenerateValue; DisplayOrder = pia.GetCustomAttributes(typeof (DWFDisplayOrderAttribute), true) .Select(p => (int?) ((DWFDisplayOrderAttribute) p).DisplayOrder) .FirstOrDefault() ?? int.MaxValue; FieldName = pi.Name; DisplayName = pia.GetDescriptionByAttribute(defaultResult: pi.Name); ControlID = typeof(T).Name + FieldName; } //accessor public WebControl CreateControl() { return DymWebFormControlMappnig.GetInst(DataType, ValidationType).CreateControl(); } public DymWebFormValidation Validation { get { return DymWebFormControlMappnig.GetInst(DataType, ValidationType).Validation; } } } internal static class FormFieldFactory { private static readonly FormField[] ArrCache; static FormFieldFactory() { var mt = typeof(T) .GetCustomAttributes(typeof(DWFMetaAttribute), true) .Select(p => ((DWFMetaAttribute)p).Type) .FirstOrDefault(); var mp = mt == null ? null : mt.GetProperties().ToDictionary(p => p.Name, p => p); var typ = typeof(T); ArrCache = typ.GetProperties() .Where(p => //using meta (mp != null && mp.ContainsKey(p.Name) && mp[p.Name].IsDefined(typeof(DWFIgnoreAttribute), true) == false) || //not using meta (mp == null && p.IsDefined(typeof(DWFIgnoreAttribute), true) == false) ) .SelectArray(p => new FormField(p)) .OrderBy(p => p.DisplayOrder) .ToArray(); } public static FormField[] GetFormFields() { return ArrCache; } public static object GetPKValue(object entity) { return GetFormFields() .Where(p => p.IsPK) .Select(p => p.GetValue((T)entity)) .First(); } public static object GetFKValue(object entity) { return GetFormFields() .Where(p => p.IsFKDisplay) .Select(p => p.GetValue((T)entity)) .First(); } } internal static class FormFieldFactoryProxy { private static readonly Dictionary> ms_dicCachePK; private static readonly Dictionary> ms_dicCacheFK; static FormFieldFactoryProxy() { ms_dicCachePK = new Dictionary>(); ms_dicCacheFK = new Dictionary>(); } public static object GetPKValue(object entity) { if (entity == null) throw new ArgumentNullException("entity"); var typ = entity.GetType(); if (ms_dicCachePK.ContainsKey(typ) == false) { var typFactory = typeof(FormFieldFactory<>).MakeGenericType(entity.GetType()); var methodName = new Func(FormFieldFactory.GetPKValue).Method.Name; ms_dicCachePK[typ] = (Func)Delegate.CreateDelegate( typeof(Func) , typFactory.GetMethod(methodName) ); } return ms_dicCachePK[typ](entity); } public static object GetFKValue(object entity) { if (entity == null) throw new ArgumentNullException("entity"); var typ = entity.GetType(); if (ms_dicCacheFK.ContainsKey(typ) == false) { var typFactory = typeof(FormFieldFactory<>).MakeGenericType(entity.GetType()); var metName = new Func(FormFieldFactory.GetFKValue).Method.Name; ms_dicCacheFK[typ] = (Func)Delegate.CreateDelegate( typeof(Func) , typFactory.GetMethod(metName) ); } return ms_dicCacheFK[typ](entity); } } }