private ChannelRef PreProcess <TRequest>(AffinityConfig affinityConfig, TRequest request)
        {
            // Gets the affinity bound key if required in the request method.
            string boundKey = null;

            if (affinityConfig != null && affinityConfig.Command == AffinityConfig.Types.Command.Bound)
            {
                boundKey = GetAffinityKeysFromProto(affinityConfig.AffinityKey, (IMessage)request).SingleOrDefault();
            }

            ChannelRef channelRef = GetChannelRef(boundKey);

            channelRef.ActiveStreamCountIncr();
            return(channelRef);
        }
 // Note: response may be default(TResponse) in the case of a failure. We only expect to be called from
 // protobuf-based calls anyway, so it will always be a class type, and will never be null for success cases.
 // We can therefore check for nullity rather than having a separate "success" parameter.
 private void PostProcess <TRequest, TResponse>(AffinityConfig affinityConfig, ChannelRef channelRef, TRequest request, TResponse response)
 {
     channelRef.ActiveStreamCountDecr();
     // Process BIND or UNBIND if the method has affinity feature enabled, but only for successful calls.
     if (affinityConfig != null && response != null)
     {
         if (affinityConfig.Command == AffinityConfig.Types.Command.Bind)
         {
             foreach (string bindingKey in GetAffinityKeysFromProto(affinityConfig.AffinityKey, (IMessage)response))
             {
                 Bind(channelRef, bindingKey);
             }
         }
         else if (affinityConfig.Command == AffinityConfig.Types.Command.Unbind)
         {
             foreach (string unbindingKey in GetAffinityKeysFromProto(affinityConfig.AffinityKey, (IMessage)request))
             {
                 Unbind(unbindingKey);
             }
         }
     }
 }