Ejemplo n.º 1
0
 public SubscribeableMethod(MethodInfo method, SubscriptionAttribute subscription, Type payloadType, Type parameterType, bool isEnvelope)
 {
     Method         = method;
     Subscription   = subscription;
     PayloadType    = payloadType;
     ParameterType  = parameterType;
     IsEnvelopeType = isEnvelope;
 }
Ejemplo n.º 2
0
        private SubscribeableMethod GetSubscribeableMethod(MethodInfo method, SubscriptionAttribute subscription)
        {
            Type payloadType = subscription.PayloadType.UnwrapEnvelopeType();

            // void MyMethod<T>(T) or void MyMethod<T>() or void MyMethod<T>(Envelope<T>)
            // If the method is generic, we can try to fill in the type parameters with the value from the attribute
            if (method.IsGenericMethodDefinition)
            {
                if (method.GetGenericArguments().Length != 1 || payloadType == null)
                {
                    _logger.Error($"Cannot subscribe method {method.Name} because method is generic and there is not enough information to construct it");
                    return(null);
                }
                method = method.MakeGenericMethod(payloadType);
            }

            Type parameterType = method.GetParameters().FirstOrDefault()?.ParameterType;

            // void MyMethod()
            // There is no parameter, so see if we have enough information to construct a trampoline
            if (parameterType == null)
            {
                // We have no type information at all, so we can't do anything
                if (payloadType == null)
                {
                    _logger.Error($"Could not determine which channel to use because payload type is not provided and there is no parameter");
                    return(null);
                }

                // This is not a fully-constructed type, so we can't determine a channel for it
                if (payloadType.IsGenericType && !payloadType.IsConstructedGenericType)
                {
                    _logger.Error($"Payload type {payloadType.Name} is not fully-constructed and cannot be used to define a channel");
                    return(null);
                }

                // Use the payload type from the attribute to create a trampoline to a method with no parameters
                return(new SubscribeableMethod(method, subscription, payloadType, null, false));
            }

            // parameterType is the type of the raw parameter, which may include Envelope<>
            // parameterPayloadType is the type of the payload without Envelope<>

            bool isEnvelope           = parameterType.IsEnvelopeType();
            Type parameterPayloadType = parameterType.UnwrapEnvelopeType();

            if (payloadType == null)
            {
                payloadType = parameterPayloadType;
            }

            // void MyMethod<T>(T payload) or void MyMethod<T>(Envelope<T> payload)
            // This is not a fully-constructed type, so we can't determine a channel for it
            if (payloadType.IsGenericType && !payloadType.IsConstructedGenericType)
            {
                _logger.Error($"Payload type {payloadType.Name} is not fully-constructed and cannot be used");
                return(null);
            }

            // Check that the type information between parameter and specified payload type are assignable
            if (!parameterPayloadType.IsAssignableFrom(payloadType))
            {
                _logger.Error($"Cannot subscribe method {method.Name} because specified payload type {payloadType.Name} is not assignable to parameter type {parameterPayloadType.Name}");
                return(null);
            }

            return(new SubscribeableMethod(method, subscription, payloadType, parameterType, isEnvelope));
        }