public static IMemberAccessor GetNamedAccessor(Type type, string name) { IMemberAccessor result = null; return(_namedAccessors.GetOrAdd($"{type.Name}-{name}", key => { var propertyInfo = type.GetTypeInfo().GetProperty(name, BindingFlags.Public | BindingFlags.Instance); if (propertyInfo != null) { result = new MethodInfoAccessor(propertyInfo.GetGetMethod()); } if (result == null) { var fieldInfo = type.GetTypeInfo().GetField(name, BindingFlags.Public | BindingFlags.Instance); if (fieldInfo != null) { result = new DelegateAccessor((o, n) => fieldInfo.GetValue(o)); } } return result; })); }
public static IMemberAccessor GetNamedAccessor(Type type, string name) { var key = String.Concat("(", type.FullName, ")", name); if (!_namedAccessors.TryGetValue(key, out var result)) { var propertyInfo = type.GetTypeInfo().GetProperty(name, BindingFlags.Public | BindingFlags.Instance); if (propertyInfo != null) { result = new MethodInfoAccessor(propertyInfo.GetGetMethod()); } if (result == null) { var fieldInfo = type.GetTypeInfo().GetField(name, BindingFlags.Public | BindingFlags.Instance); if (fieldInfo != null) { result = new DelegateAccessor((o, n) => fieldInfo.GetValue(o)); } } } return(result); }
private static List <string> GetAllMembers(Type type) { if (!_typeMembers.TryGetValue(type, out var list)) { list = new List <string>(); foreach (var propertyInfo in type.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { list.Add(propertyInfo.Name); var key = String.Concat("(", type.FullName, ")", propertyInfo.Name); _namedAccessors[key] = new MethodInfoAccessor(propertyInfo.GetGetMethod()); } foreach (var fieldInfo in type.GetTypeInfo().GetFields(BindingFlags.Public | BindingFlags.Instance)) { list.Add(fieldInfo.Name); var key = String.Concat("(", type.FullName, ")", fieldInfo.Name); _namedAccessors[key] = new DelegateAccessor((o, n) => fieldInfo.GetValue(o)); } _typeMembers[type] = list; } return(list); }
internal static Dictionary <string, IMemberAccessor> GetTypeMembers(Type type, MemberNameStrategy memberNameStrategy) { return(_typeMembers.GetOrAdd(type, t => { var list = new Dictionary <string, IMemberAccessor>(); foreach (var propertyInfo in t.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { if (propertyInfo.GetIndexParameters().Length > 0) { // Indexed property... continue; } list[memberNameStrategy(propertyInfo)] = new PropertyInfoAccessor(propertyInfo); } foreach (var fieldInfo in t.GetTypeInfo().GetFields(BindingFlags.Public | BindingFlags.Instance)) { list[memberNameStrategy(fieldInfo)] = new DelegateAccessor((o, n) => fieldInfo.GetValue(o)); } return list; })); }
internal static Dictionary <string, IMemberAccessor> GetTypeMembers(Type type, MemberNameStrategy memberNameStrategy) { return(_typeMembers.GetOrAdd(type, t => { var list = new Dictionary <string, IMemberAccessor>(); foreach (var propertyInfo in t.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { if (propertyInfo.GetIndexParameters().Length > 0) { // Indexed property... continue; } if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Task <>)) { list[memberNameStrategy(propertyInfo)] = new AsyncDelegateAccessor(async(o, n) => { var asyncValue = (Task)propertyInfo.GetValue(o); await asyncValue.ConfigureAwait(false); return (object)((dynamic)asyncValue).Result; }); } else { list[memberNameStrategy(propertyInfo)] = new PropertyInfoAccessor(propertyInfo); } } foreach (var fieldInfo in t.GetTypeInfo().GetFields(BindingFlags.Public | BindingFlags.Instance)) { if (fieldInfo.FieldType.IsGenericType && fieldInfo.FieldType.GetGenericTypeDefinition() == typeof(Task <>)) { list[memberNameStrategy(fieldInfo)] = new AsyncDelegateAccessor(async(o, n) => { var asyncValue = (Task)fieldInfo.GetValue(o); await asyncValue.ConfigureAwait(false); return (object)((dynamic)asyncValue).Result; }); } else { list[memberNameStrategy(fieldInfo)] = new DelegateAccessor((o, n) => fieldInfo.GetValue(o)); } } return list; })); }
static TypeAccessor CreateNew(Type type) { #if !NO_DYNAMIC if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(type)) { return DynamicAccessor.Singleton; } #endif PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance); ConstructorInfo ctor = null; if (type.IsClass && !type.IsAbstract) { ctor = type.GetConstructor(Type.EmptyTypes); } ILGenerator il; if (!IsFullyPublic(type)) { DynamicMethod dynGetter = new DynamicMethod(type.FullName + "_get", typeof(object), new Type[] { typeof(object), typeof(string) }, type, true), dynSetter = new DynamicMethod(type.FullName + "_set", null, new Type[] { typeof(object), typeof(string), typeof(object) }, type, true); WriteGetter(dynGetter.GetILGenerator(), type, props, fields, true); WriteSetter(dynSetter.GetILGenerator(), type, props, fields, true); DynamicMethod dynCtor = null; if (ctor != null) { dynCtor = new DynamicMethod(type.FullName + "_ctor", typeof(object), Type.EmptyTypes, type, true); il = dynCtor.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); } var delegateAccessor = new DelegateAccessor( (Func<object, string, object>)dynGetter.CreateDelegate(typeof(Func<object, string, object>)), (Action<object, string, object>)dynSetter.CreateDelegate(typeof(Action<object, string, object>)), dynCtor == null ? null : (Func<object>)dynCtor.CreateDelegate(typeof(Func<object>))); delegateAccessor.PropertyInfos = props; delegateAccessor.FieldInfos = fields; return delegateAccessor; } // note this region is synchronized; only one is being created at a time so we don't need to stress about the builders if (assembly == null) { AssemblyName name = new AssemblyName("FastMember_dynamic"); assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); module = assembly.DefineDynamicModule(name.Name); } TypeBuilder tb = module.DefineType("FastMember_dynamic." + type.Name + "_" + Interlocked.Increment(ref counter), (typeof(TypeAccessor).Attributes | TypeAttributes.Sealed) & ~TypeAttributes.Abstract, typeof(TypeAccessor)); tb.DefineDefaultConstructor(MethodAttributes.Public); PropertyInfo indexer = typeof(TypeAccessor).GetProperty("Item"); MethodInfo baseGetter = indexer.GetGetMethod(), baseSetter = indexer.GetSetMethod(); MethodBuilder body = tb.DefineMethod(baseGetter.Name, baseGetter.Attributes & ~MethodAttributes.Abstract, typeof(object), new Type[] { typeof(object), typeof(string) }); il = body.GetILGenerator(); WriteGetter(il, type, props, fields, false); tb.DefineMethodOverride(body, baseGetter); body = tb.DefineMethod(baseSetter.Name, baseSetter.Attributes & ~MethodAttributes.Abstract, null, new Type[] { typeof(object), typeof(string), typeof(object) }); il = body.GetILGenerator(); WriteSetter(il, type, props, fields, false); tb.DefineMethodOverride(body, baseSetter); if (ctor != null) { MethodInfo baseMethod = typeof(TypeAccessor).GetProperty("CreateNewSupported").GetGetMethod(); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, typeof(bool), Type.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); baseMethod = typeof(TypeAccessor).GetMethod("CreateNew"); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, typeof(object), Type.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); } var typeAccessor = (TypeAccessor)Activator.CreateInstance(tb.CreateType()); typeAccessor.PropertyInfos = props; typeAccessor.FieldInfos = fields; return typeAccessor; }
static TypeAccessor CreateNew(Type type, bool allowNonPublicAccessors) { if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(type)) { return(DynamicAccessor.Singleton); } BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; if (allowNonPublicAccessors) { flags |= BindingFlags.NonPublic; } PropertyInfo[] props = type.GetTypeAndInterfaceProperties(flags); FieldInfo[] fields = type.GetFields(flags); Dictionary <string, int> map = new Dictionary <string, int>(); List <MemberInfo> members = new List <MemberInfo>(props.Length + fields.Length); List <Member> mems = new List <Member>(); int i = 0; foreach (var prop in props) { if (!map.ContainsKey(prop.Name) && prop.GetIndexParameters().Length == 0) { map.Add(prop.Name, i++); members.Add(prop); } } foreach (var field in fields) { if (!map.ContainsKey(field.Name)) { map.Add(field.Name, i++); members.Add(field); } } foreach (MemberInfo mem in members) { mems.Add(new Member(mem)); } ConstructorInfo ctor = null; if (type.IsClass && !type.IsAbstract) { ctor = type.GetConstructor(Type.EmptyTypes); } ILGenerator il; if (!IsFullyPublic(type, props, fields, allowNonPublicAccessors)) { DynamicMethod dynGetter = new DynamicMethod(type.FullName + "_get", typeof(object), new Type[] { typeof(int), typeof(object) }, type, true), dynSetter = new DynamicMethod(type.FullName + "_set", null, new Type[] { typeof(int), typeof(object), typeof(object) }, type, true); WriteMapImpl(dynGetter.GetILGenerator(), type, members, null, allowNonPublicAccessors, true); WriteMapImpl(dynSetter.GetILGenerator(), type, members, null, allowNonPublicAccessors, false); DynamicMethod dynCtor = null; if (ctor != null) { dynCtor = new DynamicMethod(type.FullName + "_ctor", typeof(object), Type.EmptyTypes, type, true); il = dynCtor.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); } DelegateAccessor a = new DelegateAccessor( map, (Func <int, object, object>)dynGetter.CreateDelegate(typeof(Func <int, object, object>)), (Action <int, object, object>)dynSetter.CreateDelegate(typeof(Action <int, object, object>)), dynCtor == null ? null : (Func <object>)dynCtor.CreateDelegate(typeof(Func <object>)), type); a.Members = mems; return(a); } // note this region is synchronized; only one is being created at a time so we don't need to stress about the builders if (assembly == null) { AssemblyName name = new AssemblyName("FastMember_dynamic"); assembly = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); module = assembly.DefineDynamicModule(name.Name); } TypeAttributes attribs = typeof(TypeAccessor).Attributes; TypeBuilder tb = module.DefineType("FastMember_dynamic." + type.Name + "_" + GetNextCounterValue(), (attribs | TypeAttributes.Sealed | TypeAttributes.Public) & ~(TypeAttributes.Abstract | TypeAttributes.NotPublic), typeof(RuntimeTypeAccessor)); il = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] { typeof(Dictionary <string, int>) }).GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); FieldBuilder mapField = tb.DefineField("_map", typeof(Dictionary <string, int>), FieldAttributes.InitOnly | FieldAttributes.Private); il.Emit(OpCodes.Stfld, mapField); il.Emit(OpCodes.Ret); PropertyInfo indexer = typeof(TypeAccessor).GetProperty("Item"); MethodInfo baseGetter = indexer.GetGetMethod(), baseSetter = indexer.GetSetMethod(); MethodBuilder body = tb.DefineMethod(baseGetter.Name, baseGetter.Attributes & ~MethodAttributes.Abstract, typeof(object), new Type[] { typeof(object), typeof(string) }); il = body.GetILGenerator(); WriteMapImpl(il, type, members, mapField, allowNonPublicAccessors, true); tb.DefineMethodOverride(body, baseGetter); body = tb.DefineMethod(baseSetter.Name, baseSetter.Attributes & ~MethodAttributes.Abstract, null, new Type[] { typeof(object), typeof(string), typeof(object) }); il = body.GetILGenerator(); WriteMapImpl(il, type, members, mapField, allowNonPublicAccessors, false); tb.DefineMethodOverride(body, baseSetter); MethodInfo baseMethod; if (ctor != null) { baseMethod = typeof(TypeAccessor).GetProperty("CreateNewSupported").GetGetMethod(); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType, Type.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); baseMethod = typeof(TypeAccessor).GetMethod("CreateNew"); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType, Type.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); } baseMethod = typeof(RuntimeTypeAccessor).GetProperty("Type", BindingFlags.NonPublic | BindingFlags.Instance).GetGetMethod(true); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes & ~MethodAttributes.Abstract, baseMethod.ReturnType, Type.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Ldtoken, type); il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); var accessor = (TypeAccessor)Activator.CreateInstance(tb.CreateTypeInfo().AsType(), map); accessor.Members = mems; return(accessor); }
static TypeAccessor CreateNew(Type type) { #if !NO_DYNAMIC if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(type)) { return(DynamicAccessor.Singleton); } #endif PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance); ConstructorInfo ctor = null; if (type.IsClass && !type.IsAbstract) { ctor = type.GetConstructor(Type.EmptyTypes); } ILGenerator il; if (!IsFullyPublic(type)) { DynamicMethod dynGetter = new DynamicMethod(type.FullName + "_get", typeof(object), new Type[] { typeof(object), typeof(string) }, type, true), dynSetter = new DynamicMethod(type.FullName + "_set", null, new Type[] { typeof(object), typeof(string), typeof(object) }, type, true); WriteGetter(dynGetter.GetILGenerator(), type, props, fields, true); WriteSetter(dynSetter.GetILGenerator(), type, props, fields, true); DynamicMethod dynCtor = null; if (ctor != null) { dynCtor = new DynamicMethod(type.FullName + "_ctor", typeof(object), Type.EmptyTypes, type, true); il = dynCtor.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); } var delegateAccessor = new DelegateAccessor( (Func <object, string, object>)dynGetter.CreateDelegate(typeof(Func <object, string, object>)), (Action <object, string, object>)dynSetter.CreateDelegate(typeof(Action <object, string, object>)), dynCtor == null ? null : (Func <object>)dynCtor.CreateDelegate(typeof(Func <object>))); delegateAccessor.PropertyInfos = props; delegateAccessor.FieldInfos = fields; return(delegateAccessor); } // note this region is synchronized; only one is being created at a time so we don't need to stress about the builders if (assembly == null) { AssemblyName name = new AssemblyName("FastMember_dynamic"); assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); module = assembly.DefineDynamicModule(name.Name); } TypeBuilder tb = module.DefineType("FastMember_dynamic." + type.Name + "_" + Interlocked.Increment(ref counter), (typeof(TypeAccessor).Attributes | TypeAttributes.Sealed) & ~TypeAttributes.Abstract, typeof(TypeAccessor)); tb.DefineDefaultConstructor(MethodAttributes.Public); PropertyInfo indexer = typeof(TypeAccessor).GetProperty("Item"); MethodInfo baseGetter = indexer.GetGetMethod(), baseSetter = indexer.GetSetMethod(); MethodBuilder body = tb.DefineMethod(baseGetter.Name, baseGetter.Attributes & ~MethodAttributes.Abstract, typeof(object), new Type[] { typeof(object), typeof(string) }); il = body.GetILGenerator(); WriteGetter(il, type, props, fields, false); tb.DefineMethodOverride(body, baseGetter); body = tb.DefineMethod(baseSetter.Name, baseSetter.Attributes & ~MethodAttributes.Abstract, null, new Type[] { typeof(object), typeof(string), typeof(object) }); il = body.GetILGenerator(); WriteSetter(il, type, props, fields, false); tb.DefineMethodOverride(body, baseSetter); if (ctor != null) { MethodInfo baseMethod = typeof(TypeAccessor).GetProperty("CreateNewSupported").GetGetMethod(); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, typeof(bool), Type.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); baseMethod = typeof(TypeAccessor).GetMethod("CreateNew"); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, typeof(object), Type.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); } var typeAccessor = (TypeAccessor)Activator.CreateInstance(tb.CreateType()); typeAccessor.PropertyInfos = props; typeAccessor.FieldInfos = fields; return(typeAccessor); }