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); }
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; }
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; }