public IDisposable Add(string method, IJsonRpcHandler handler, JsonRpcHandlerOptions options)
        {
            var type       = handler.GetType();
            var @interface = HandlerTypeDescriptorHelper.GetHandlerInterface(type);

            Type @params  = null;
            Type response = null;

            if (@interface.GetTypeInfo().IsGenericType)
            {
                @params = @interface.GetTypeInfo().GetGenericArguments()[0];
                var requestInterface = @params.GetInterfaces()
                                       .FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IRequest <>));
                if (requestInterface != null)
                {
                    response = requestInterface.GetGenericArguments()[0];
                }
            }

            var requestProcessType =
                options?.RequestProcessType ??
                _handlerTypeDescriptorProvider.GetHandlerTypeDescriptor(type)?.RequestProcessType ??
                type.GetCustomAttributes(true)
                .Concat(@interface.GetCustomAttributes(true))
                .OfType <ProcessAttribute>()
                .FirstOrDefault()?.Type;

            var descriptor = new HandlerInstance(method, handler, @interface, @params, response, requestProcessType, () => Remove(handler));

            ImmutableInterlocked.InterlockedExchange(ref _descriptors, _descriptors.Add(descriptor));
            return(descriptor);
        }
예제 #2
0
        public HandlerTypeDescriptor(Type handlerType)
        {
            var method = MethodAttribute.From(handlerType) !;

            Method    = method.Method;
            Direction = method.Direction;
            if (handlerType.IsGenericTypeDefinition && handlerType.IsPublic)
            {
                var parameter   = handlerType.GetTypeInfo().GenericTypeParameters[0];
                var constraints = parameter.GetGenericParameterConstraints();
                if (constraints.Length == 1)
                {
                    handlerType = handlerType.MakeGenericType(handlerType.GetTypeInfo().GenericTypeParameters[0].GetGenericParameterConstraints()[0]);
                }
            }

            HandlerType   = handlerType;
            InterfaceType = HandlerTypeDescriptorHelper.GetHandlerInterface(handlerType);

            // This allows for us to have derived types
            // We are making the assumption that interface given here
            // if a GTD will have a constraint on the first generic type parameter
            // that is the real base type for this interface.
            if (InterfaceType.IsGenericType)
            {
                ParamsType = InterfaceType.GetGenericArguments()[0];
            }

            HasParamsType  = ParamsType != null;
            IsNotification = handlerType
                             .GetInterfaces()
                             .Any(z => z.IsGenericType && typeof(IJsonRpcNotificationHandler <>).IsAssignableFrom(z.GetGenericTypeDefinition()));
            IsRequest = !IsNotification;

            var requestInterface = ParamsType?
                                   .GetInterfaces()
                                   .FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IRequest <>));

            if (requestInterface != null)
            {
                ResponseType = requestInterface.GetGenericArguments()[0];
            }
            HasResponseType = ResponseType != null && ResponseType != typeof(Unit);

            var processAttributes = HandlerType
                                    .GetCustomAttributes(true)
                                    .Concat(HandlerType.GetCustomAttributes(true))
                                    .Concat(InterfaceType.GetInterfaces().SelectMany(x => x.GetCustomAttributes(true)))
                                    .Concat(HandlerType.GetInterfaces().SelectMany(x => x.GetCustomAttributes(true)))
                                    .OfType <ProcessAttribute>()
                                    .ToArray();

            RequestProcessType = processAttributes
                                 .FirstOrDefault()?.Type;
        }
예제 #3
0
        public HandlerTypeDescriptor(Type handlerType)
        {
            var method = handlerType.GetCustomAttribute <MethodAttribute>();

            Method        = method.Method;
            Direction     = method.Direction;
            HandlerType   = handlerType;
            InterfaceType = HandlerTypeDescriptorHelper.GetHandlerInterface(handlerType);

            ParamsType    = InterfaceType.IsGenericType ? InterfaceType.GetGenericArguments()[0] : typeof(EmptyRequest);
            HasParamsType = ParamsType != null && ParamsType != typeof(EmptyRequest);

            IsNotification = typeof(IJsonRpcNotificationHandler).IsAssignableFrom(handlerType) || handlerType
                             .GetInterfaces().Any(z =>
                                                  z.IsGenericType && typeof(IJsonRpcNotificationHandler <>).IsAssignableFrom(z.GetGenericTypeDefinition()));
            IsRequest = !IsNotification;

            var requestInterface = ParamsType?
                                   .GetInterfaces()
                                   .FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IRequest <>));

            if (requestInterface != null)
            {
                ResponseType = requestInterface.GetGenericArguments()[0];
            }
            HasResponseType = ResponseType != null && ResponseType != typeof(Unit);

            var processAttributes = HandlerType
                                    .GetCustomAttributes(true)
                                    .Concat(HandlerType.GetCustomAttributes(true))
                                    .Concat(InterfaceType.GetInterfaces().SelectMany(x => x.GetCustomAttributes(true)))
                                    .Concat(HandlerType.GetInterfaces().SelectMany(x => x.GetCustomAttributes(true)))
                                    .OfType <ProcessAttribute>()
                                    .ToArray();

            RequestProcessType = processAttributes
                                 .FirstOrDefault()?.Type;
        }