public virtual IConsumer Resolve(ConsumerDescriptor descriptor) { if (descriptor.PluginDescriptor == null || IsActiveForStore(descriptor.PluginDescriptor)) { return(_container.Value.ResolveKeyed <IConsumer>(descriptor.ContainerType)); } return(null); }
public ConsumerRegistry(IEnumerable <Lazy <IConsumer, EventConsumerMetadata> > consumers) { foreach (var consumer in consumers) { var metadata = consumer.Metadata; if (!metadata.IsActive) { continue; } var methods = FindMethods(metadata); var messageTypes = new Dictionary <Type, MethodInfo>(); foreach (var method in methods) { var descriptor = new ConsumerDescriptor(metadata) { IsAsync = method.ReturnType == typeof(Task), FireForget = method.HasAttribute <FireForgetAttribute>(false) }; //if (descriptor.IsAsync && descriptor.FireForget) //{ // throw new NotSupportedException($"An asynchronous message consumer method cannot be called as fire & forget. Method: '{method}'."); //} if (method.ReturnType != typeof(Task) && method.ReturnType != typeof(void)) { throw new NotSupportedException($"A message consumer method's return type must either be 'void' or '${typeof(Task).FullName}'. Method: '{method}'."); } if (method.Name.EndsWith("Async") && !descriptor.IsAsync) { throw new NotSupportedException($"A synchronous message consumer method name should not end with 'Async'. Method: '{method}'."); } var parameters = method.GetParameters(); if (parameters.Length == 0) { throw new NotSupportedException($"A message consumer method must have at least one parameter identifying the message to consume. Method: '{method}'."); } if (parameters.Any(x => x.ParameterType.IsByRef || x.IsOut || x.IsOptional)) { throw new NotSupportedException($"'out', 'ref' and optional parameters are not allowed in consumer methods. Method: '{method}'."); } var p = parameters[0]; var messageType = p.ParameterType; if (messageType.IsGenericType && messageType.GetGenericTypeDefinition() == typeof(ConsumeContext <>)) { messageType = messageType.GetGenericArguments()[0]; descriptor.WithEnvelope = true; } if (messageTypes.TryGetValue(messageType, out var method2)) { // We won't allow methods with different signatures, but same message type: there can only be one! throw new AmbigousConsumerException(method2, method); } messageTypes.Add(messageType, method); if (messageType.IsPublic && (messageType.IsClass || messageType.IsInterface)) { // The method signature is valid: add to dictionary. descriptor.MessageParameter = p; descriptor.Parameters = parameters.Skip(1).ToArray(); descriptor.MessageType = messageType; descriptor.Method = method; _descriptorMap.Add(messageType, descriptor); } else { // TODO: message throw new NotSupportedException(); } } } }