Beispiel #1
0
        public static T CreateProxy <T>(this HubConnection connection)
        {
            var  impl     = new Implementer <T>();
            bool isIProxy = typeof(IProxy).IsAssignableFrom(typeof(T));

            if (isIProxy)
            {
                impl.Member(o => ((IProxy)o).Connection).Returns(connection);
            }

            foreach (var method in impl.Methods.Where(o => (typeof(T).IsInterface || o.IsVirtual) && !o.IsSpecialName && o.IsPublic && typeof(Task).IsAssignableFrom(o.ReturnType)))
            {
                var invokeMethod           = ResolveInvokeMethod(method);
                int invokeMethodParamCount = invokeMethod.GetParameters().Length;

                impl.Member <object>(method).Callback(args =>
                {
                    var invokeArgs = new object[invokeMethodParamCount];
                    invokeArgs[0]  = connection;
                    invokeArgs[1]  = method.Name;

                    for (int i = 0; i < args.Count; i++)
                    {
                        invokeArgs[i + 2] = args.Values.ElementAt(i);
                    }

                    return(invokeMethod.Invoke(null, invokeArgs));
                });
            }

            return(impl.Finish());
        }
Beispiel #2
0
        internal static TData GenerateDataObject(object dataObject)
        {
            if (!typeof(TData).IsInterface)
            {
                throw new Exception($"{nameof(TData)} must be an interface type");
            }

            if (ImplDataCache == null)
            {
                var impl = new Implementer <TData>(dataObject.GetType());

                foreach (var prop in impl.Properties)
                {
                    if (prop.GetMethod != null)
                    {
                        impl.Getter(prop).Callback(o =>
                        {
                            var file = o["__data"] as ReadableDataFile;

                            return(file.GetNonGeneric(
                                       type: prop.PropertyType,
                                       key: prop.Name
                                       ));
                        });
                    }

                    if (prop.SetMethod != null)
                    {
                        impl.Setter(prop, (value, data) =>
                        {
                            var file = (ReadableWritableDataFile)data;
                            file?.SetNonGeneric(
                                type: prop.PropertyType,
                                key: prop.Name,
                                value);
                        });
                    }
                }

                ImplDataCache = impl.Finish();
            }

            return(ClassUtils.Copy(ImplDataCache, dataObject));
        }
Beispiel #3
0
        /// <summary>
        /// Creates a proxy type for this queue. If <typeparamref name="T"/> is an interface, every method
        /// will be overriden to call <see cref="Call(string, Type, object[])"/>. If it isn't an interface,
        /// all of its virtual or abstract methods will be overriden instead.
        /// </summary>
        /// <typeparam name="T">The type of the proxy to create</typeparam>
        public T CreateProxy <T>()
        {
            CheckDisposed();

            var impl = new Implementer <T>();

            foreach (var item in impl.Methods.Where(o => o.DeclaringType == typeof(T)))
            {
                var returnType = item.ReturnType;

                if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task <>))
                {
                    returnType = returnType.GenericTypeArguments[0];
                }

                impl.Member(item).Callback(args =>
                {
                    if (typeof(Task).IsAssignableFrom(item.ReturnType))
                    {
                        var callMethod = this
                                         .GetType()
#if NETSTANDARD2_1 || NETCOREAPP3_0
                                         .GetMethod("Call", 1, new[] { typeof(string), typeof(object[]) })
#else
                                         .GetMethods()
                                         .Single(o => o.ContainsGenericParameters && o
                                                 .GetParameters()
                                                 .Select(o => o.ParameterType)
                                                 .SequenceEqual(new[] { typeof(string), typeof(object[]) }))
#endif
                                         .MakeGenericMethod(returnType);

                        return(callMethod.Invoke(this, new object[] { item.Name, args.Values.ToArray() }));
                    }
                    else
                    {
                        return(Call(item.Name, returnType, args.Values.ToArray()).Result);
                    }
                });
            }

            return(impl.Finish());
        }