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; }
private void GenerateMethods() { var methodNames = new HashSet <string>(); var allMethods = new List <MethodInfo>(); foreach (MethodInfo method in InterfaceType .GetMethods(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public) .Concat( InterfaceType.GetInterfaces() .SelectMany( x => x.GetMethods(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public))) .OrderBy(x => x.Name)) { if (!methodNames.Add(method.Name)) { throw new ArgumentException( string.Format("The type contains at least two methods with the same name '{0}': This is not supported", method.Name)); } allMethods.Add(method); } foreach (var method in allMethods) { if (method.IsSpecialName) { var methodName = method.Name; if (methodName.StartsWith("add_")) { GenerateAddEvent(method); } else if (methodName.StartsWith("remove_")) { GenerateRemoveEvent(method); } else { GenerateMethodInvocation(method); } } else { GenerateMethodInvocation(method); } } }
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; }