private static AccessorMember MaybeSwapMetadataMember(ICustomAttributeProvider authority, AccessorMember member, string profile) { foreach (var attribute in authority.GetAttributes <MetadataTypeAttribute>()) { if (attribute.Profile != profile) { continue; } var types = AccessorMemberTypes.None; types |= member.MemberType switch { AccessorMemberType.Field => AccessorMemberTypes.Fields, AccessorMemberType.Property => AccessorMemberTypes.Properties, AccessorMemberType.Method => AccessorMemberTypes.Methods, _ => throw new ArgumentOutOfRangeException() }; var members = AccessorMembers.Create(attribute.MetadataType, types, member.Scope); foreach (var m in members) { if (m.Name != member.Name) { continue; } member = m; break; } } return(member); }
private static ITypeCallAccessor CreateTypeCallAccessor(Type type, AccessorMemberScope scope = AccessorMemberScope.All) { var members = AccessorMembers.Create(type, AccessorMemberTypes.Methods, scope); var name = type.CreateNameForCallAccessor(); var tb = DynamicAssembly.Module.DefineType( name, TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoClass | TypeAttributes.AnsiClass); tb.AddInterfaceImplementation(typeof(ITypeCallAccessor)); // // Type Type =>: // tb.MemberProperty(nameof(ITypeCallAccessor.Type), type, typeof(ITypeCallAccessor).GetMethod($"get_{nameof(ITypeCallAccessor.Type)}")); // // object Call(object target, string name, params object[] args): // { var call = tb.DefineMethod(nameof(ITypeCallAccessor.Call), MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.NewSlot, typeof(object), new[] { typeof(object), typeof(string), typeof(object[]) }); var il = call.GetILGeneratorInternal(); var branches = new Dictionary <AccessorMember, Label>(); foreach (var member in members) { if (!member.IsInstanceMethod) { continue; } branches.Add(member, il.DefineLabel()); } il.DeclareLocal(typeof(string)); il.DeclareLocal(typeof(object)); il.Nop(); il.Ldarg_2(); il.Stloc_0(); foreach (var member in members) { if (!member.IsInstanceMethod) { continue; } il.Ldloc_0(); il.GotoIfStringEquals(member.Name, branches[member]); } foreach (var member in members) { if (!member.IsInstanceMethod) { continue; } var method = (MethodInfo)member.MemberInfo; var parameters = method.GetParameters(); var parameterTypes = parameters.Select(p => p.ParameterType).ToArray(); il.MarkLabel(branches[member]); il.Ldarg_1(); il.CastOrUnbox(method.DeclaringType); var returns = method.ReturnType != typeof(void); if (returns) { continue; throw new NotImplementedException(); } if (parameters.Length > 0) { il.Ldarg_3(); il.Ldc_I4_S((byte)parameters.Length); il.Ldelem_Ref(); il.Unbox_Any(parameterTypes[0]); } il.Callvirt(method); il.Nop(); il.Ldtoken(typeof(void)); il.CallOrCallvirt(type, KnownMethods.GetTypeFromHandle); il.Stloc_1(); il.Ldloc_1(); il.Ret(); } il.Newobj(typeof(ArgumentNullException).GetConstructor(Type.EmptyTypes)); il.Throw(); tb.DefineMethodOverride(call, typeof(ITypeCallAccessor).GetMethod(nameof(ITypeCallAccessor.Call))); } var typeInfo = tb.CreateTypeInfo(); return((ITypeCallAccessor)Activator.CreateInstance(typeInfo.AsType(), false)); }
private static AccessorMembers CreateReadAccessorMembers(Type type, AccessorMemberTypes types = AccessorMemberTypes.Fields | AccessorMemberTypes.Properties, AccessorMemberScope scope = AccessorMemberScope.All) { return(AccessorMembers.Create(type, types, scope)); }
private static AccessorMembers CreateAnonymousReadAccessorMembers(Type type) { return(AccessorMembers.Create(type, AccessorMemberTypes.Properties, AccessorMemberScope.Public)); }
private static AccessorMembers CreateWriteAccessorMembers(Type type, AccessorMemberTypes types, AccessorMemberScope scope) { return(AccessorMembers.Create(type, types, scope)); }