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());
        }
Example #2
0
        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());
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
            }
        }