private void BuildAnnotatedMessageHandlers() { // create a handler for every method which has MessageHandlerAttribute var methods = _type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var method in methods) { var attr = method.GetCustomAttribute <MessageHandlerAttribute>(); if (attr == null) { continue; } var messageType = attr.Type ?? method.GetParameters()[0].ParameterType; var isAsyncMethod = (method.ReturnType.Name.StartsWith("Task")); var filterChain = _filterHandlerBuilder.Build(method, FilterChainKind.Message); var isSyncHandler = isAsyncMethod == false && filterChain.AsyncFilterExists == false; var isReentrant = isSyncHandler == false && HandlerBuilderHelpers.IsReentrantMethod(method); if (isAsyncMethod == false && method.GetCustomAttribute <AsyncStateMachineAttribute>() != null) { throw new InvalidOperationException($"Async void handler is not supported. ({_type.FullName}.{method.Name})"); } AddHandler(method, messageType, filterChain, isSyncHandler, isReentrant); } }
private void BuildRegularInterfaceHandlers() { foreach (var ifs in _type.GetInterfaces()) { if (ifs.GetInterfaces().All(t => t != typeof(IInterfacedObserver) && t != typeof(IInterfacedObserverSync))) { continue; } var primaryInterface = ifs; var alternativeInterfaceAttribute = ifs.GetCustomAttribute <AlternativeInterfaceAttribute>(); if (alternativeInterfaceAttribute != null) { primaryInterface = alternativeInterfaceAttribute.Type.IsGenericType ? alternativeInterfaceAttribute.Type.MakeGenericType(ifs.GetGenericArguments()) : alternativeInterfaceAttribute.Type; } var interfaceMap = _type.GetInterfaceMap(ifs); var methodItems = interfaceMap.InterfaceMethods.Zip(interfaceMap.TargetMethods, Tuple.Create) .OrderBy(p => p.Item1, new MethodInfoComparer()) .ToArray(); var payloadTypeTable = GetInterfacePayloadTypeTable(primaryInterface); // build a decorated handler for each method. for (var i = 0; i < methodItems.Length; i++) { var targetMethod = methodItems[i].Item2; var invokePayloadType = payloadTypeTable[i]; var filterChain = _filterHandlerBuilder.Build(targetMethod, FilterChainKind.Notification); var isSyncHandler = alternativeInterfaceAttribute == null && filterChain.AsyncFilterExists == false; var isReentrant = isSyncHandler == false && HandlerBuilderHelpers.IsReentrantMethod(targetMethod); AddHandler(ifs, targetMethod, invokePayloadType, filterChain, isSyncHandler, isReentrant); } } }