internal static FieldInfo[] GetBindableMembers(TypeInfo typeInfo) { /* * var rpcInterface = GetRpcInterface(); * if (rpcInterface != null) * { * var rpcInterfaceMap = typeInfo.GetInterfaceMap(rpcInterface); * //members = rpcInterfaceMap.TargetMethods; * } */ Type baseType; if (ReflectionSerializerVerifier.HasRdExtAttribute(typeInfo)) { baseType = typeof(RdExtReflectionBindableBase); } else if (ReflectionSerializerVerifier.HasRdModelAttribute(typeInfo)) { baseType = typeof(RdReflectionBindableBase); } else { baseType = typeof(RdBindableBase); } bool isRdExtImpl = baseType == typeof(RdExtReflectionBindableBase) && !typeInfo.GetInterfaces().Contains(typeof(IProxyTypeMarker)); bool isRdRpcInterface = typeInfo.IsInterface; // can be specified in RdExt // && typeInfo.GetCustomAttribute<RdRpcAttribute>() != null; var fields = GetFields(typeInfo, baseType); var list = new List <FieldInfo>(); foreach (var mi in fields) { if (typeof(RdExtReflectionBindableBase).IsAssignableFrom(mi.FieldType)) { continue; } if ( mi.MemberType == MemberTypes.Field && (mi.DeclaringType != null && !mi.DeclaringType.GetTypeInfo().IsAssignableFrom(baseType)) && mi.GetCustomAttribute <NonSerializedAttribute>() == null && // arbitrary data is allowed in RdExt implementations since they don't have to be serializable !(isRdExtImpl && ReflectionSerializerVerifier.IsScalar(ReflectionSerializerVerifier.GetImplementingType(mi.FieldType.GetTypeInfo()))) ) { list.Add(mi); } else if (isRdRpcInterface) { throw new Exception($"Invalid member in RdRpc interface: {typeInfo.ToString(true)}.{mi.Name}"); } } return(list.ToArray()); }
internal static FieldInfo[] GetBindableMembers(TypeInfo typeInfo) { /* * var rpcInterface = GetRpcInterface(); * if (rpcInterface != null) * { * var rpcInterfaceMap = typeInfo.GetInterfaceMap(rpcInterface); * //members = rpcInterfaceMap.TargetMethods; * } */ Type baseType; if (ReflectionSerializerVerifier.HasRdExtAttribute(typeInfo)) { baseType = typeof(RdExtReflectionBindableBase); } else if (ReflectionSerializerVerifier.HasRdModelAttribute(typeInfo)) { baseType = typeof(RdReflectionBindableBase); } else { baseType = typeof(RdBindableBase); } bool isRdExt = baseType == typeof(RdExtReflectionBindableBase); var members = GetFields(typeInfo, baseType); var list = new List <FieldInfo>(); foreach (var mi in members) { if ( mi.MemberType == MemberTypes.Field && (mi.DeclaringType != null && !mi.DeclaringType.GetTypeInfo().IsAssignableFrom(baseType)) && mi.GetCustomAttribute <NonSerializedAttribute>() == null && // arbitrary data is allowed in RdExt since they don't have to be serializable !(isRdExt && ReflectionSerializerVerifier.IsScalar(ReflectionSerializerVerifier.GetImplementingType(mi.FieldType.GetTypeInfo()))) ) { list.Add(mi); } } return(list.ToArray()); }
private SerializerPair GetMemberSerializer(MemberInfo member, TypeInfo typeInfo) { var implementingType = ReflectionSerializerVerifier.GetImplementingType(typeInfo); var implementingTypeInfo = implementingType.GetTypeInfo(); if (mySerializers.TryGetValue(typeInfo.AsType(), out var pair)) { return(pair); } if (ReflectionSerializerVerifier.IsValueTuple(implementingTypeInfo)) { return((SerializerPair)ReflectionUtil.InvokeGenericThis(this, nameof(CreateValueTupleSerializer), typeInfo.AsType())); } var hasRdAttribute = ReflectionSerializerVerifier.HasRdModelAttribute(typeInfo) || ReflectionSerializerVerifier.HasRdExtAttribute(typeInfo); if (typeInfo.IsGenericType && !hasRdAttribute) { return(CreateGenericSerializer(member, typeInfo, implementingType, implementingTypeInfo)); } if (typeInfo.IsEnum) { var serializer = ReflectionUtil.InvokeGenericThis(this, nameof(CreateEnumSerializer), typeInfo.AsType()); return((SerializerPair)serializer); } if (typeInfo.IsArray) { var serializer = ReflectionUtil.InvokeGenericThis(this, nameof(CreateArraySerializer), typeInfo.GetElementType()); return((SerializerPair)serializer); } if (hasRdAttribute) { return(GetOrRegisterSerializerInternal(typeInfo.AsType())); } Assertion.Fail($"Unable to serialize member: {member.DeclaringType?.ToString(true)}.{member.Name} of type {typeInfo.ToString(true)}"); return(null); }
private object ReflectionInitInternal(object instance) { var typeInfo = instance.GetType().GetTypeInfo(); if (ReflectionSerializerVerifier.HasRdExtAttribute(instance.GetType().GetTypeInfo())) { ReflectionSerializerVerifier.AssertValidRdExt(typeInfo); } foreach (var mi in SerializerReflectionUtil.GetBindableMembers(typeInfo)) { ReflectionSerializerVerifier.AssertMemberDeclaration(mi); var currentValue = ReflectionUtil.GetGetter(mi)(instance); if (currentValue == null) { currentValue = ActivateRdExtMember(mi); var memberSetter = ReflectionUtil.GetSetter(mi); memberSetter(instance, currentValue); } else { var implementingType = ReflectionSerializerVerifier.GetImplementingType(ReflectionUtil.GetReturnType(mi).GetTypeInfo()); Assertion.Assert(currentValue.GetType() == implementingType, "Bindable field {0} was initialized with incompatible type. Expected type {1}, actual {2}", mi, implementingType.ToString(true), currentValue.GetType().ToString(true)); } } // Add RdEndpoint for Impl class (counterpart of Proxy) var interfaces = typeInfo.GetInterfaces(); bool isProxy = interfaces.Contains(typeof(IProxyTypeMarker)); var rpcInterface = ReflectionSerializersFactory.GetRpcInterface(typeInfo); if (!isProxy && rpcInterface != null) { var bindableChildren = ((IReflectionBindable)instance).BindableChildren; var interfaceMap = typeInfo.GetInterfaceMap(rpcInterface); var interfaceMethods = interfaceMap.InterfaceMethods; // Dynamic adapters for Properties are not required, so skip them var ignoreMethods = new HashSet <string>(StringComparer.Ordinal); foreach (var propertyInfo in rpcInterface.GetProperties(BindingFlags.Instance | BindingFlags.Public)) { ignoreMethods.Add(propertyInfo.GetSetMethod()?.Name); ignoreMethods.Add(propertyInfo.GetGetMethod()?.Name); } foreach (var interfaceMethod in interfaceMethods) { if (ignoreMethods.Contains(interfaceMethod.Name)) { continue; } var adapter = myProxyGenerator.CreateAdapter(rpcInterface, interfaceMethod); var name = ProxyGenerator.ProxyFieldName(interfaceMethod); var requestType = ProxyGenerator.GetRequstType(interfaceMethod)[0]; EnsureFakeTupleRegistered(requestType); var responseNonTaskType = ProxyGenerator.GetResponseType(interfaceMethod, unwrapTask: true); var responseType = ProxyGenerator.GetResponseType(interfaceMethod, unwrapTask: false); var endPointType = typeof(RdCall <,>).MakeGenericType(requestType, responseNonTaskType); var endpoint = ActivateGenericMember(name, endPointType.GetTypeInfo()); SetAsync(interfaceMethod, endpoint); if (endpoint is RdReactiveBase reactiveBase) { reactiveBase.ValueCanBeNull = true; } if (ProxyGenerator.IsSync(interfaceMethod)) { var delType = typeof(Func <, ,>).MakeGenericType(typeof(Lifetime), requestType, typeof(RdTask <>).MakeGenericType(responseNonTaskType)); var @delegate = adapter.CreateDelegate(delType, instance); var methodInfo = typeof(ReflectionRdActivator).GetMethod(nameof(SetHandler)).NotNull().MakeGenericMethod(requestType, responseNonTaskType); methodInfo.Invoke(null, new[] { endpoint, @delegate }); } else { if (responseType == typeof(Task)) { var delType = typeof(Func <, ,>).MakeGenericType(typeof(Lifetime), requestType, typeof(Task)); var @delegate = adapter.CreateDelegate(delType, instance); var methodInfo = typeof(ReflectionRdActivator).GetMethod(nameof(SetHandlerTaskVoid)).NotNull().MakeGenericMethod(requestType); methodInfo.Invoke(null, new[] { endpoint, @delegate }); } else { var delType = typeof(Func <, ,>).MakeGenericType(typeof(Lifetime), requestType, typeof(Task <>).MakeGenericType(responseNonTaskType)); var @delegate = adapter.CreateDelegate(delType, instance); var methodInfo = typeof(ReflectionRdActivator).GetMethod(nameof(SetHandlerTask)).NotNull().MakeGenericMethod(requestType, responseNonTaskType); methodInfo.Invoke(null, new[] { endpoint, @delegate }); } } bindableChildren.Add(new KeyValuePair <string, object>(name, endpoint)); } } else if (rpcInterface != null) { foreach (var interfaceMethod in rpcInterface.GetMethods()) { var requestType = ProxyGenerator.GetRequstType(interfaceMethod)[0]; EnsureFakeTupleRegistered(requestType); } } // Allow initialize to setup bindings to composite properties. if (instance is IReflectionBindable reflectionBindable) { reflectionBindable.OnActivated(); } return(instance); }
internal SerializerPair GetOrCreateMemberSerializer([NotNull] MemberInfo mi, [NotNull] Type serializerType, bool allowNullable) { if (!allowNullable) { ReflectionSerializerVerifier.AssertMemberDeclaration(mi); } else { ReflectionSerializerVerifier.AssertDataMemberDeclaration(mi); } var typeInfo = serializerType.GetTypeInfo(); var implementingType = ReflectionSerializerVerifier.GetImplementingType(typeInfo); var implementingTypeInfo = implementingType.GetTypeInfo(); if (typeInfo.IsGenericType && !(ReflectionSerializerVerifier.HasRdModelAttribute(typeInfo) || ReflectionSerializerVerifier.HasRdExtAttribute(typeInfo))) { return(CreateGenericSerializer(mi, typeInfo, implementingType)); } else if (ReflectionSerializerVerifier.IsScalar(serializerType)) { return(GetOrCreateScalar(serializerType, false)); } else { var serializerPair = GetOrRegisterStaticSerializerInternal(serializerType, false); Assertion.AssertNotNull(serializerPair != null, $"Unable to Create serializer for type {serializerType.ToString(true)}"); if (serializerPair == null) { #if JET_MODE_ASSERT Assertion.Fail($"Unable to create serializer for {serializerType.ToString(true)}: circular dependency detected: {String.Join(" -> ", myCurrentSerializersChain.Select(t => t.ToString(true)).ToArray())}"); #endif throw new Assertion.AssertionException($"Undetected circular dependency during serializing {serializerType.ToString(true)}"); } return(serializerPair); } }