public static AreParameterTypesEqual ( |
||
a | ||
b | ||
return | bool |
private void BuildExtendedInterfaceHandlers() { var targetMethods = _type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) .Where(m => m.GetCustomAttribute <ExtendedHandlerAttribute>() != null) .Select(m => Tuple.Create(m, m.GetCustomAttribute <ExtendedHandlerAttribute>())) .ToList(); var extendedInterfaces = _type.GetInterfaces() .Where(t => t.FullName.StartsWith("Akka.Interfaced.IExtendedInterface")) .SelectMany(t => t.GenericTypeArguments) .Where(t => t.GetInterfaces().Any(i => i == typeof(IInterfacedActor))) .ToArray(); // includes base interfaces var extendedAllInterfaces = extendedInterfaces .Concat(extendedInterfaces.SelectMany(t => t.GetInterfaces().Where(u => u != typeof(IInterfacedActor)))) .Distinct().ToArray(); foreach (var ifs in extendedAllInterfaces) { var payloadTypeTable = GetInterfacePayloadTypeTable(ifs); var interfaceMethods = ifs.GetMethods().OrderBy(m => m, new MethodInfoComparer()).ToArray(); for (var i = 0; i < interfaceMethods.Length; i++) { var interfaceMethod = interfaceMethods[i]; var invokePayloadType = payloadTypeTable[i, 0]; var returnPayloadType = payloadTypeTable[i, 1]; var name = interfaceMethod.Name; var parameters = interfaceMethod.GetParameters(); // find a method which can handle this invoke payload MethodInfo targetMethod = null; foreach (var method in targetMethods) { if (method.Item2.Type != null || method.Item2.Method != null) { // check tagged method if (method.Item2.Type != null && method.Item2.Type != ifs) { continue; } if (method.Item2.Method != null && method.Item2.Method != name) { continue; } } else if (method.Item1.Name != name) { // check method continue; } if (HandlerBuilderHelpers.AreParameterTypesEqual(method.Item1.GetParameters(), parameters)) { if (targetMethod != null) { throw new InvalidOperationException( $"Ambiguous handlers for {ifs.FullName}.{interfaceMethod.Name} method.\n" + $" {targetMethod.Name}\n {method.Item1.Name}\n"); } targetMethod = method.Item1; } } if (targetMethod == null) { throw new InvalidOperationException( $"Cannot find handler for {ifs.FullName}.{interfaceMethod.Name}"); } targetMethods.RemoveAll(x => x.Item1 == targetMethod); // build handler var isAsyncMethod = targetMethod.ReturnType.Name.StartsWith("Task"); var filterChain = _filterHandlerBuilder.Build(targetMethod, FilterChainKind.Request); var isSyncHandler = isAsyncMethod == false && filterChain.AsyncFilterExists == false; var isReentrant = isSyncHandler == false && HandlerBuilderHelpers.IsReentrantMethod(targetMethod); if (isAsyncMethod == false && targetMethod.GetCustomAttribute <AsyncStateMachineAttribute>() != null) { throw new InvalidOperationException($"Async void handler is not supported. ({_type.FullName}.{targetMethod.Name})"); } AddHandler(ifs, targetMethod, invokePayloadType, returnPayloadType, filterChain, isSyncHandler, isReentrant); } } }