THRIFT-4839: Remove embedded buffering/framed options from TCP transports
Client: netstd
Patch: Kyle Smith + minor changes by Jens Geyer

This closes #1770
diff --git a/tutorial/netstd/Client/Client.csproj b/tutorial/netstd/Client/Client.csproj
index 70eae15..a1470a9 100644
--- a/tutorial/netstd/Client/Client.csproj
+++ b/tutorial/netstd/Client/Client.csproj
@@ -30,6 +30,10 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
+  </ItemGroup>
+
+  <ItemGroup>
     <ProjectReference Include="..\Interfaces\Interfaces.csproj" />
     <ProjectReference Include="..\..\..\lib\netstd\Thrift\Thrift.csproj" />
   </ItemGroup>
diff --git a/tutorial/netstd/Client/Program.cs b/tutorial/netstd/Client/Program.cs
index 4b68cee..f9509fa 100644
--- a/tutorial/netstd/Client/Program.cs
+++ b/tutorial/netstd/Client/Program.cs
@@ -32,6 +32,7 @@
 using tutorial;
 using shared;
 using Microsoft.Extensions.DependencyInjection;
+using System.Diagnostics;
 
 namespace Client
 {
@@ -47,17 +48,20 @@
     Client.exe -help
         will diplay help information 
 
-    Client.exe -tr:<transport> -pr:<protocol> -mc:<numClients>
+    Client.exe -tr:<transport> -bf:<buffering> -pr:<protocol> -mc:<numClients>
         will run client with specified arguments (tcp transport and binary protocol by default) and with 1 client
 
 Options:
     -tr (transport): 
         tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
-        tcpbuffered - buffered transport over tcp will be used (host - ""localhost"", port - 9090)
         namedpipe - namedpipe transport will be used (pipe address - "".test"")
         http - http transport will be used (address - ""http://localhost:9090"")        
         tcptls - tcp tls transport will be used (host - ""localhost"", port - 9090)
-        framed - tcp framed transport will be used (host - ""localhost"", port - 9090)
+
+    -bf (buffering): 
+        none - (default) no buffering will be used
+        buffered - buffered transport will be used
+        framed - framed transport will be used
 
     -pr (protocol): 
         binary - (default) binary protocol will be used
@@ -139,29 +143,57 @@
 
         private static TTransport GetTransport(string[] args)
         {
-            var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1];
+            TTransport transport = new TSocketTransport(IPAddress.Loopback, 9090);
 
-            Transport selectedTransport;
-            if (Enum.TryParse(transport, true, out selectedTransport))
+            // construct endpoint transport
+            var transportArg = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1];
+            if (Enum.TryParse(transportArg, true, out Transport selectedTransport))
             {
                 switch (selectedTransport)
                 {
                     case Transport.Tcp:
-                        return new TSocketTransport(IPAddress.Loopback, 9090);
+                        transport = new TSocketTransport(IPAddress.Loopback, 9090);
+                        break;
+
                     case Transport.NamedPipe:
-                        return new TNamedPipeTransport(".test");
+                        transport = new TNamedPipeTransport(".test");
+                        break;
+
                     case Transport.Http:
-                        return new THttpTransport(new Uri("http://localhost:9090"), null);
-                    case Transport.TcpBuffered:
-                        return new TBufferedTransport(new TSocketTransport(IPAddress.Loopback, 9090));
+                        transport = new THttpTransport(new Uri("http://localhost:9090"), null);
+                        break;
+
                     case Transport.TcpTls:
-                        return new TTlsSocketTransport(IPAddress.Loopback, 9090, GetCertificate(), CertValidator, LocalCertificateSelectionCallback);
-                    case Transport.Framed:
-                        return new TFramedTransport(new TSocketTransport(IPAddress.Loopback, 9090));
+                        transport = new TTlsSocketTransport(IPAddress.Loopback, 9090, GetCertificate(), CertValidator, LocalCertificateSelectionCallback);
+                        break;
+
+                    default:
+                        Debug.Assert(false, "unhandled case");
+                        break;
                 }
             }
 
-            return new TSocketTransport(IPAddress.Loopback, 9090);
+            // optionally add layered transport(s)
+            var bufferingArg = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(':')?[1];
+            if (Enum.TryParse<Buffering>(bufferingArg, out var selectedBuffering))
+            {
+                switch (selectedBuffering)
+                {
+                    case Buffering.Buffered:
+                        transport = new TBufferedTransport(transport);
+                        break;
+
+                    case Buffering.Framed:
+                        transport = new TFramedTransport(transport);
+                        break;
+
+                    default: // layered transport(s) are optional
+                        Debug.Assert(selectedBuffering == Buffering.None, "unhandled case");
+                        break;
+                }
+            }
+
+            return transport;
         }
 
         private static int GetNumberOfClients(string[] args)
@@ -231,6 +263,9 @@
                     case Protocol.Multiplexed:
                         // it returns BinaryProtocol to avoid making wrapped protocol as public in TProtocolDecorator (in RunClientAsync it will be wrapped into Multiplexed protocol)
                         return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
+                    default:
+                        Debug.Assert(false, "unhandled case");
+                        break;
                 }
             }
 
@@ -363,5 +398,12 @@
             Json,
             Multiplexed
         }
+
+        private enum Buffering
+        {
+            None,
+            Buffered,
+            Framed
+        }
     }
 }