예제 #1
0
        public static string GetMethodName(Type type)
        {
            if (MethodNames.TryGetValue(type, out var method))
            {
                return(method);
            }

            // Custom method
            var attribute = MethodAttribute.From(type);

            var handler = KnownHandlers.SelectMany(z => z)
                          .FirstOrDefault(z => z.InterfaceType == type || z.HandlerType == type || z.ParamsType == type);

            if (handler != null)
            {
                return(handler.Method);
            }

            // TODO: Log unknown method name
            if (attribute is null)
            {
                return(null);
            }

            MethodNames.TryAdd(type, attribute.Method);
            return(attribute.Method);
        }
예제 #2
0
 static HandlerTypeDescriptorHelper()
 {
     try
     {
         KnownHandlers = AppDomain.CurrentDomain.GetAssemblies()
                         .SelectMany(
             x => {
             try
             {
                 return(x.GetTypes());
             }
             catch
             {
                 return(Enumerable.Empty <Type>());
             }
         }
             )
                         .Where(z => (z.IsInterface || (z.IsClass && !z.IsAbstract)) && typeof(IJsonRpcHandler).IsAssignableFrom(z))
                         .Where(z => MethodAttribute.From(z) != null)
                         .Where(z => !z.Name.EndsWith("Manager"))          // Manager interfaces are generally specializations around the handlers
                         .Select(GetMethodType)
                         .Distinct()
                         .ToLookup(x => MethodAttribute.From(x).Method)
                         .SelectMany(x => x.Select(z => new HandlerTypeDescriptor(z) as IHandlerTypeDescriptor))
                         .ToLookup(x => x.Method, StringComparer.Ordinal);
     }
     catch (Exception e)
     {
         throw new AggregateException("Failed", e);
     }
 }
예제 #3
0
 internal static IEnumerable <IHandlerTypeDescriptor> GetDescriptors(IEnumerable <Assembly> assemblies) => assemblies.SelectMany(
     x => {
     try
     {
         return(x.GetTypes());
     }
     catch
     {
         return(Enumerable.Empty <Type>());
     }
 }
     )
 .Where(z => z.IsInterface || z.IsClass && !z.IsAbstract)
 // running on mono this call can cause issues when scanning of the entire assembly.
 .Where(
     z => {
     try
     {
         return(typeof(IJsonRpcHandler).IsAssignableFrom(z));
     }
     catch
     {
         return(false);
     }
 }
     )
 .Where(z => MethodAttribute.From(z) != null)
 .Where(z => !z.Name.EndsWith("Manager"))    // Manager interfaces are generally specializations around the handlers
 .Select(HandlerTypeDescriptorHelper.GetMethodType)
 .Distinct()
 .ToLookup(x => MethodAttribute.From(x) !.Method)
예제 #4
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;
        }
예제 #5
0
        internal static Type GetMethodType(Type type)
        {
            // Custom method
            if (MethodAttribute.AllFrom(type).Any())
            {
                return(type);
            }

            return(type.GetTypeInfo()
                   .ImplementedInterfaces
                   .FirstOrDefault(t => MethodAttribute.AllFrom(t).Any()));
        }