Example #1
0
        /// <summary>
        /// Checks that callback method has signature "void (StreamingContext)" and compiles it.
        /// </summary>
        private static Action <object, StreamingContext> CompileCallbackMethod(MethodInfo method)
        {
            Debug.Assert(method != null);
            Debug.Assert(method.DeclaringType != null);

            var parameters = method.GetParameters();

            if (method.ReturnType != typeof(void) || parameters.Length != 1 ||
                parameters[0].ParameterType != typeof(StreamingContext))
            {
                throw new TypeLoadException(
                          string.Format("Type '{0}' in assembly '{1}' has method '{2}' with an incorrect " +
                                        "signature for the serialization attribute that it is decorated with.",
                                        method.DeclaringType, method.DeclaringType.Assembly, method.Name));
            }

            return(DelegateConverter.CompileFunc <Action <object, StreamingContext> >(
                       method.DeclaringType, method, new[] { typeof(StreamingContext) }, new[] { false, false }));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DelegateTypeDescriptor"/> class.
        /// </summary>
        /// <param name="type">The type.</param>
        private DelegateTypeDescriptor(Type type)
        {
            foreach (var iface in type.GetInterfaces())
            {
                if (!iface.IsGenericType)
                {
                    continue;
                }

                var genericTypeDefinition = iface.GetGenericTypeDefinition();

                if (genericTypeDefinition == typeof(IComputeFunc <>))
                {
                    ThrowIfMultipleInterfaces(_computeOutFunc, type, typeof(IComputeFunc <>));

                    _computeOutFunc = DelegateConverter.CompileFunc(iface);
                }
                else if (genericTypeDefinition == typeof(IComputeFunc <,>))
                {
                    ThrowIfMultipleInterfaces(_computeFunc, type, typeof(IComputeFunc <,>));

                    var args = iface.GetGenericArguments();

                    _computeFunc = DelegateConverter.CompileFunc <Func <object, object, object> >(iface, new[] { args[0] });
                }
                else if (genericTypeDefinition == typeof(IEventFilter <>))
                {
                    ThrowIfMultipleInterfaces(_eventFilter, type, typeof(IEventFilter <>));

                    var args = iface.GetGenericArguments();

                    _eventFilter = DelegateConverter.CompileFunc <Func <object, object, bool> >(iface,
                                                                                                new[] { args[0] }, new[] { true, false });
                }
                else if (genericTypeDefinition == typeof(ICacheEntryFilter <,>))
                {
                    ThrowIfMultipleInterfaces(_cacheEntryFilter, type, typeof(ICacheEntryFilter <,>));

                    var args = iface.GetGenericArguments();

                    var entryType = typeof(ICacheEntry <,>).MakeGenericType(args);

                    var invokeFunc = DelegateConverter.CompileFunc <Func <object, object, bool> >(iface,
                                                                                                  new[] { entryType }, new[] { true, false });

                    var ctor = DelegateConverter.CompileCtor <Func <object, object, object> >(
                        typeof(CacheEntry <,>).MakeGenericType(args), args);

                    // Resulting func constructs CacheEntry and passes it to user implementation
                    _cacheEntryFilter = (obj, k, v) => invokeFunc(obj, ctor(k, v));
                }
                else if (genericTypeDefinition == typeof(ICacheEntryProcessor <, , ,>))
                {
                    ThrowIfMultipleInterfaces(_cacheEntryProcessor, type, typeof(ICacheEntryProcessor <, , ,>));

                    var args = iface.GetGenericArguments();

                    var entryType = typeof(IMutableCacheEntry <,>).MakeGenericType(args[0], args[1]);

                    var func = DelegateConverter.CompileFunc <Func <object, object, object, object> >(iface,
                                                                                                      new[] { entryType, args[2] }, null, "Process");

                    var types = new Tuple <Type, Type>(args[0], args[1]);

                    _cacheEntryProcessor = new Tuple <Func <object, IMutableCacheEntryInternal, object, object>, Tuple <Type, Type> >
                                               (func, types);

                    var transformerType = typeof(StreamTransformer <, , ,>).MakeGenericType(args);

                    _streamTransformerCtor = DelegateConverter.CompileCtor <Func <object, object> >(transformerType,
                                                                                                    new[] { iface });
                }
                else if (genericTypeDefinition == typeof(IMessageListener <>))
                {
                    ThrowIfMultipleInterfaces(_messageLsnr, type, typeof(IMessageListener <>));

                    var arg = iface.GetGenericArguments()[0];

                    _messageLsnr = DelegateConverter.CompileFunc <Func <object, Guid, object, bool> >(iface,
                                                                                                      new[] { typeof(Guid), arg }, new[] { false, true, false });
                }
                else if (genericTypeDefinition == typeof(IComputeJob <>))
                {
                    ThrowIfMultipleInterfaces(_messageLsnr, type, typeof(IComputeJob <>));

                    _computeJobExecute = DelegateConverter.CompileFunc <Func <object, object> >(iface, new Type[0],
                                                                                                methodName: "Execute");

                    _computeJobCancel = DelegateConverter.CompileFunc <Action <object> >(iface, new Type[0],
                                                                                         new[] { false }, "Cancel");
                }
                else if (genericTypeDefinition == typeof(IStreamReceiver <,>))
                {
                    ThrowIfMultipleInterfaces(_streamReceiver, type, typeof(IStreamReceiver <,>));

                    var method =
                        typeof(StreamReceiverHolder).GetMethod("InvokeReceiver")
                        .MakeGenericMethod(iface.GetGenericArguments());

                    _streamReceiver = DelegateConverter
                                      .CompileFunc <Action <object, Ignite, IPlatformTargetInternal, IBinaryStream, bool> >(
                        typeof(StreamReceiverHolder),
                        method,
                        new[]
                    {
                        iface, typeof(Ignite), typeof(IPlatformTargetInternal), typeof(IBinaryStream),
                        typeof(bool)
                    },
                        new[] { true, false, false, false, false, false });
                }
                else if (genericTypeDefinition == typeof(ICacheEntryEventFilter <,>))
                {
                    ThrowIfMultipleInterfaces(_streamReceiver, type, typeof(ICacheEntryEventFilter <,>));

                    var args = iface.GetGenericArguments();

                    _continuousQueryFilterCtor =
                        DelegateConverter.CompileCtor <Func <object, object, object> >(
                            typeof(ContinuousQueryFilter <,>).MakeGenericType(args), new[] { iface, typeof(bool) });
                }
            }
        }