Summary

Class:CBAM.Abstractions.Implementation.NetworkStream.StatefulProtocolConnectionFactory`10
Assembly:CBAM.Abstractions.Implementation.NetworkStream
File(s):/repo-dir/contents/Source/Code/CBAM.Abstractions.Implementation.NetworkStream/ConnectionFactory.Stateful.cs
Covered lines:43
Uncovered lines:8
Coverable lines:51
Total lines:397
Line coverage:84.3%
Branch coverage:45%

Coverage History

Metrics

MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage
.ctor(...)201%1%
IsDedicatedStringPool(...)201%0.5%
ResetFactoryState()400%0%
GetStringPoolForNewConnection()401%0.25%
CreateConnectionFunctionality()800.789%1%

File(s)

/repo-dir/contents/Source/Code/CBAM.Abstractions.Implementation.NetworkStream/ConnectionFactory.Stateful.cs

#LineLine coverage
 1/*
 2 * Copyright 2018 Stanislav Muhametsin. All rights Reserved.
 3 *
 4 * Licensed  under the  Apache License,  Version 2.0  (the "License");
 5 * you may not use  this file  except in  compliance with the License.
 6 * You may obtain a copy of the License at
 7 *
 8 *   http://www.apache.org/licenses/LICENSE-2.0
 9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed  under the  License is distributed on an "AS IS" BASIS,
 12 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
 13 * implied.
 14 *
 15 * See the License for the specific language governing permissions and
 16 * limitations under the License.
 17 */
 18using IOUtils.Network.Configuration;
 19using ResourcePooling.Async.Abstractions;
 20using System;
 21using System.Threading;
 22using System.Threading.Tasks;
 23using UtilPack;
 24using System.Net;
 25using System.IO;
 26
 27#if !NETSTANDARD1_0
 28using IOUtils.Network.ResourcePooling;
 29#endif
 30
 31namespace CBAM.Abstractions.Implementation.NetworkStream
 32{
 33   /// <summary>
 34   /// This class extends <see cref="ConnectionFactoryStream{TConnection, TPrivateConnection, TConnectionFunctionality, 
 35   /// Notice that this need for state does not always correlate whether the underlying protocol itself is stateless or 
 36   /// </summary>
 37   /// <typeparam name="TConnection">The public type of <see cref="Connection{TStatement, TStatementInformation, TStatem
 38   /// <typeparam name="TPrivateConnection">The actual type of <see cref="Connection{TStatement, TStatementInformation, 
 39   /// <typeparam name="TConnectionFunctionality">The actual type of <see cref="PooledConnectionFunctionality{TStatement
 40   /// <typeparam name="TIntermediateState">The type of the intermediate state used during connection initialization.</t
 41   /// <typeparam name="TConnectionCreationParameters">The type of parameter containing enough information to create an 
 42   /// <typeparam name="TCreationData">The type holding passive data about the remote endpoint and protocol configuratio
 43   /// <typeparam name="TConnectionConfiguration">The type holding passive data about the socket connection.</typeparam>
 44   /// <typeparam name="TInitializationConfiguration">The type holding passive data about protocol initialization.</type
 45   /// <typeparam name="TProtocolConfiguration">The type holding passive data about protocol.</typeparam>
 46   /// <typeparam name="TPoolingConfiguration">The type holding passive data about pooling behaviour.</typeparam>
 47   public abstract class StatefulProtocolConnectionFactory<TConnection, TPrivateConnection, TConnectionFunctionality, TI
 48      where TConnection : class
 49      where TPrivateConnection : class, TConnection
 50      where TConnectionFunctionality : class, PooledConnectionFunctionality
 51      where TConnectionCreationParameters : NetworkConnectionCreationInfo<TCreationData, TConnectionConfiguration, TInit
 52      where TCreationData : NetworkConnectionCreationInfoData<TConnectionConfiguration, TInitializationConfiguration, TP
 53      where TConnectionConfiguration : NetworkConnectionConfiguration
 54      where TInitializationConfiguration : NetworkInitializationConfiguration<TProtocolConfiguration, TPoolingConfigurat
 55      where TPoolingConfiguration : NetworkPoolingConfiguration
 56   {
 57      private readonly CreateIntermediateStateDelegate<TConnectionCreationParameters, TIntermediateState> _createInterme
 58      private readonly Boolean _dedicatedStringPoolNeedsToBeConcurrent;
 59
 60
 61      /// <summary>
 62      /// Creates a new instance of <see cref="StatelessProtocolConnectionFactory{TConnection, TPrivateConnection, TConn
 63      /// </summary>
 64      /// <param name="creationInfo">The connection creation parameters.</param>
 65      /// <param name="encodingInfo">The <see cref="IEncodingInfo"/> to use when (de)serializing strings.</param>
 66      /// <param name="createIntermediateState">The callback to create intermediate state to hold during connection init
 67      /// <param name="isSSLPossible">The callback to check if remote end supports SSL.</param>
 68      /// <param name="noSSLStreamProvider">The callback to create an exception when there was not possible to create SS
 69      /// <param name="remoteNoSSLSupport">The callback to create an exception when the remote does not support SSL. May
 70      /// <param name="sslStreamProviderNoStream">The callback to create an exception when the SSL stream creation callb
 71      /// <param name="sslStreamProviderNoAuthenticationCallback">The callback to create an exception when the SSL strea
 72      /// <param name="sslStreamOtherError">The callback to create an exception when other error occurs during SSL strea
 73      /// <param name="dedicatedStringPoolNeedsToBeConcurrent">A boolean indicating whether per-connection dedicated str
 74      /// <exception cref="ArgumentNullException">If any of the <paramref name="creationInfo"/>, <paramref name="encodin
 75      public StatefulProtocolConnectionFactory(
 76         TConnectionCreationParameters creationInfo,
 77         IEncodingInfo encodingInfo,
 78         CreateIntermediateStateDelegate<TConnectionCreationParameters, TIntermediateState> createIntermediateState,
 79         IsSSLPossibleDelegate<TConnectionCreationParameters, TIntermediateState> isSSLPossible,
 80         Func<Exception> noSSLStreamProvider,
 81         Func<Exception> remoteNoSSLSupport,
 82         Func<Exception> sslStreamProviderNoStream,
 83         Func<Exception> sslStreamProviderNoAuthenticationCallback,
 84         Func<Exception, Exception> sslStreamOtherError,
 85         Boolean dedicatedStringPoolNeedsToBeConcurrent
 2586         ) : base( creationInfo )
 87      {
 2588         this.Encoding = ArgumentValidator.ValidateNotNull( nameof( encodingInfo ), encodingInfo );
 2589         ArgumentValidator.ValidateNotNull( nameof( creationInfo ), creationInfo );
 2590         this._createIntermediateState = ArgumentValidator.ValidateNotNull( nameof( createIntermediateState ), createInt
 2591         this._dedicatedStringPoolNeedsToBeConcurrent = dedicatedStringPoolNeedsToBeConcurrent;
 92
 2593         var encoding = encodingInfo.Encoding;
 94#if NETSTANDARD1_0
 95         if ( !( creationInfo.CreationData?.Initialization?.ConnectionPool?.ConnectionsOwnStringPool ?? default ) )
 96         {
 97            this.GlobalStringPool = BinaryStringPoolFactory.NewConcurrentBinaryStringPool( encoding );
 98         }
 99#else
 25100         (this.NetworkStreamConfiguration, this.RemoteAddress, this.GlobalStringPool) = creationInfo.CreateStatefulNetwo
 25101            ( socket, stream, token ) =>
 25102            {
 53103               var stringPool = this.GetStringPoolForNewConnection();
 25104
 53105               return (stringPool, this._createIntermediateState( this.CreationParameters, this.Encoding, stringPool, th
 25106            },
 25107            encoding,
 53108            state => isSSLPossible?.Invoke( this.CreationParameters, this.Encoding, state.Item1, this.IsDedicatedStringP
 25109            noSSLStreamProvider,
 25110            remoteNoSSLSupport,
 25111            sslStreamProviderNoStream,
 25112            sslStreamProviderNoAuthenticationCallback,
 25113            sslStreamOtherError
 25114            );
 53115         this.NetworkStreamConfiguration.TransformStreamAfterCreation = stream => new DuplexBufferedAsyncStream( stream 
 116#endif
 25117      }
 118
 119      /// <summary>
 120      /// Gets the <see cref="IEncodingInfo"/> used to (de)serialize strings.
 121      /// </summary>
 122      /// <value>The <see cref="IEncodingInfo"/> used to (de)serialize strings.</value>
 84123      protected IEncodingInfo Encoding { get; }
 124
 125      /// <summary>
 126      /// Gets the <see cref="BinaryStringPool"/> shared between all connections created by this factory. May be <c>null
 127      /// </summary>
 128      /// <value>the <see cref="BinaryStringPool"/> shared between all connections created by this factory.</value>
 112129      protected BinaryStringPool GlobalStringPool { get; }
 130
 131      /// <summary>
 132      /// Helper method to check whether the <see cref="BinaryStringPool"/> is not <c>null</c> and is dedicated to the c
 133      /// </summary>
 134      /// <param name="stringPool">The <see cref="BinaryStringPool"/> to check.</param>
 135      /// <returns><c>true</c> if given <paramref name="stringPool"/> is not <c>null</c> and is dedicated to the connect
 136      protected Boolean IsDedicatedStringPool( BinaryStringPool stringPool )
 137      {
 56138         return stringPool != null && !ReferenceEquals( this.GlobalStringPool, stringPool );
 139      }
 140
 141#if !NETSTANDARD1_0
 142
 143      /// <summary>
 144      /// Gets the lazily asynchronous <see cref="IPAddress"/> of the remote endpoint. May be <c>null</c> (if e.g. conne
 145      /// </summary>
 146      /// <value>The lazily asynchronous <see cref="IPAddress"/> of the remote endpoint.</value>
 0147      protected ReadOnlyResettableAsyncLazy<IPAddress> RemoteAddress { get; }
 148
 149      /// <summary>
 150      /// Gets the <see cref="NetworkStreamFactoryConfiguration{TState}"/> that is used by the factory when creating new
 151      /// </summary>
 152      /// <value>The <see cref="NetworkStreamFactoryConfiguration{TState}"/> that is used by the factory when creating n
 153      /// <remarks>
 154      /// This configuration has different state than <typeparamref name="TIntermediateState"/>, because the factory nee
 155      /// </remarks>
 53156      protected NetworkStreamFactoryConfiguration<(BinaryStringPool, TIntermediateState)> NetworkStreamConfiguration { g
 157#endif
 158
 159      /// <summary>
 160      /// Implements <see cref="ResourceFactoryInformation.ResetFactoryState"/> and resets this string pool, and remote 
 161      /// </summary>
 162      public override void ResetFactoryState()
 163      {
 0164         this.GlobalStringPool?.ClearPool();
 165#if !NETSTANDARD1_0
 0166         this.RemoteAddress?.Reset();
 167#endif
 0168      }
 169
 170      private BinaryStringPool GetStringPoolForNewConnection()
 171      {
 28172         return this.GlobalStringPool ?? ( this._dedicatedStringPoolNeedsToBeConcurrent ? BinaryStringPoolFactory.NewNot
 173      }
 174
 175      /// <summary>
 176      /// Implements <see cref="DefaultConnectionFactory{TConnection, TPrivateConnection, TConnectionFunctionality, TCon
 177      /// </summary>
 178      /// <param name="token">The cancellation token to use during initialization process.</param>
 179      /// <returns>Potentially asynchronously returns an instance of <typeparamref name="TConnectionFunctionality"/>.</r
 180      protected override async ValueTask<TConnectionFunctionality> CreateConnectionFunctionality( CancellationToken toke
 181      {
 182
 28183         var parameters = this.CreationParameters;
 28184         var streamFactory = parameters.StreamFactory;
 185
 186#if NETSTANDARD1_0
 187         Object
 188#else
 189         System.Net.Sockets.Socket
 190#endif
 191             socket;
 192         Stream stream;
 193         (BinaryStringPool, TIntermediateState) state;
 28194         if ( streamFactory == null )
 195         {
 196#if NETSTANDARD1_0
 197            throw new ArgumentNullException( nameof( streamFactory ) );
 198#else
 28199            (socket, stream, state) = await NetworkStreamFactory<(BinaryStringPool, TIntermediateState)>.AcquireNetworkS
 28200                  this.NetworkStreamConfiguration,
 28201                  token );
 202#endif
 28203         }
 204         else
 205         {
 0206            socket = null;
 0207            stream = await streamFactory();
 0208            var stringPool = this.GetStringPoolForNewConnection();
 0209            state = (stringPool, this._createIntermediateState( this.CreationParameters, this.Encoding, stringPool, this
 210         }
 211
 28212         return await this.CreateFunctionality(
 28213            state.Item1,
 28214            stream,
 28215            socket,
 28216            token,
 28217            state.Item2
 28218            );
 28219      }
 220
 221      /// <summary>
 222      /// Derived classes should implement this in order to create <typeparamref name="TConnectionFunctionality"/> from 
 223      /// </summary>
 224      /// <param name="stringPool">The possibly dedicated string pool to use for the connection being created.</param>
 225      /// <param name="acquiredStream">The <see cref="Stream"/> that has been acquired and is ready to use.</param>
 226      /// <param name="socketOrNull">A socket that has been acquired, or <c>null</c> if <see cref="NetworkConnectionCrea
 227      /// <param name="token">The <see cref="CancellationToken"/> to use.</param>
 228      /// <param name="intermediateState">The intermediate state used during connection initialization.</param>
 229      /// <returns>Potentially asynchronously creates an instance of <typeparamref name="TConnectionFunctionality"/>.</r
 230      protected abstract ValueTask<TConnectionFunctionality> CreateFunctionality(
 231         BinaryStringPool stringPool,
 232         Stream acquiredStream,
 233         Object socketOrNull,
 234         CancellationToken token,
 235         TIntermediateState intermediateState
 236         );
 237   }
 238
 239
 240   /// <summary>
 241   /// This class extends and implements all missing functionality from <see cref="StatefulProtocolConnectionFactory{TCo
 242   /// </summary>
 243   /// <typeparam name="TConnection">The public type of <see cref="Connection{TStatement, TStatementInformation, TStatem
 244   /// <typeparam name="TPrivateConnection">The actual type of <see cref="Connection{TStatement, TStatementInformation, 
 245   /// <typeparam name="TConnectionFunctionality">The actual type of <see cref="PooledConnectionFunctionality{TStatement
 246   /// <typeparam name="TIntermediateState">The type of the intermediate state used during connection initialization.</t
 247   /// <typeparam name="TConnectionCreationParameters">The type of parameter containing enough information to create an 
 248   /// <typeparam name="TCreationData">The type holding passive data about the remote endpoint and protocol configuratio
 249   /// <typeparam name="TConnectionConfiguration">The type holding passive data about the socket connection.</typeparam>
 250   /// <typeparam name="TInitializationConfiguration">The type holding passive data about protocol initialization.</type
 251   /// <typeparam name="TProtocolConfiguration">The type holding passive data about protocol.</typeparam>
 252   /// <typeparam name="TPoolingConfiguration">The type holding passive data about pooling behaviour.</typeparam>
 253   public sealed class DelegatingStatefulProtocolConnectionFactory<TConnection, TPrivateConnection, TConnectionFunctiona
 254      where TConnection : class
 255      where TPrivateConnection : class, TConnection
 256      where TConnectionFunctionality : class, PooledConnectionFunctionality
 257      where TConnectionCreationParameters : NetworkConnectionCreationInfo<TCreationData, TConnectionConfiguration, TInit
 258      where TCreationData : NetworkConnectionCreationInfoData<TConnectionConfiguration, TInitializationConfiguration, TP
 259      where TConnectionConfiguration : NetworkConnectionConfiguration
 260      where TInitializationConfiguration : NetworkInitializationConfiguration<TProtocolConfiguration, TPoolingConfigurat
 261      where TPoolingConfiguration : NetworkPoolingConfiguration
 262   {
 263      private readonly CreatePrivateConnectionDelegate<TConnectionFunctionality, TPrivateConnection> _createConnection;
 264      private readonly CreateConnectionAcquireInfo<TConnectionFunctionality, TPrivateConnection> _createConnectionAcquir
 265      private readonly CreateConnectionFunctionality<TConnectionFunctionality, TIntermediateState, TConnectionCreationPa
 266      private readonly ExtractStreamOnConnectionAcquirementErrorDelegate<TConnectionFunctionality, TPrivateConnection> _
 267
 268      /// <summary>
 269      /// Creates a new instance of <see cref="DelegatingStatefulProtocolConnectionFactory{TConnection, TPrivateConnecti
 270      /// </summary>
 271      /// <param name="creationInfo">The connection creation parameters.</param>
 272      /// <param name="encodingInfo">The <see cref="IEncodingInfo"/> to use when (de)serializing strings.</param>
 273      /// <param name="createIntermediateState">The callback to create intermediate state to hold during connection init
 274      /// <param name="isSSLPossible">The callback to check if remote end supports SSL.</param>
 275      /// <param name="noSSLStreamProvider">The callback to create an exception when there was not possible to create SS
 276      /// <param name="remoteNoSSLSupport">The callback to create an exception when the remote does not support SSL. May
 277      /// <param name="sslStreamProviderNoStream">The callback to create an exception when the SSL stream creation callb
 278      /// <param name="sslStreamProviderNoAuthenticationCallback">The callback to create an exception when the SSL strea
 279      /// <param name="sslStreamOtherError">The callback to create an exception when other error occurs during SSL strea
 280      /// <param name="dedicatedStringPoolNeedsToBeConcurrent">A boolean indicating whether per-connection dedicated str
 281      /// <param name="createFunctionality">The callback for <see cref="StatelessProtocolConnectionFactory{TConnection, 
 282      /// <param name="createConnection">The callback for <see cref="DefaultConnectionFactory{TConnection, TPrivateConne
 283      /// <param name="createConnectionAcquireInfo">The callback for <see cref="DefaultConnectionFactory{TConnection, TP
 284      /// <param name="extractStreamOnConnectionAcquirementError">The callback for <see cref="ConnectionFactoryStream{TC
 285      /// <exception cref="ArgumentNullException">If any of the <paramref name="creationInfo"/>, <paramref name="encodin
 286
 287      public DelegatingStatefulProtocolConnectionFactory(
 288         TConnectionCreationParameters creationInfo,
 289         IEncodingInfo encodingInfo,
 290         CreateIntermediateStateDelegate<TConnectionCreationParameters, TIntermediateState> createIntermediateState,
 291         IsSSLPossibleDelegate<TConnectionCreationParameters, TIntermediateState> isSSLPossible,
 292         Func<Exception> noSSLStreamProvider,
 293         Func<Exception> remoteNoSSLSupport,
 294         Func<Exception> sslStreamProviderNoStream,
 295         Func<Exception> sslStreamProviderNoAuthenticationCallback,
 296         Func<Exception, Exception> sslStreamOtherError,
 297         Boolean dedicatedStringPoolNeedsToBeConcurrent,
 298         CreateConnectionFunctionality<TConnectionFunctionality, TIntermediateState, TConnectionCreationParameters> crea
 299         CreatePrivateConnectionDelegate<TConnectionFunctionality, TPrivateConnection> createConnection,
 300         CreateConnectionAcquireInfo<TConnectionFunctionality, TPrivateConnection> createConnectionAcquireInfo,
 301         ExtractStreamOnConnectionAcquirementErrorDelegate<TConnectionFunctionality, TPrivateConnection> extractStreamOn
 302         ) : base( creationInfo, encodingInfo, createIntermediateState, isSSLPossible, noSSLStreamProvider, remoteNoSSLS
 303      {
 304         this._createConnection = ArgumentValidator.ValidateNotNull( nameof( createConnection ), createConnection );
 305         this._createConnectionAcquireInfo = ArgumentValidator.ValidateNotNull( nameof( createConnectionAcquireInfo ), c
 306         this._createFunctionality = ArgumentValidator.ValidateNotNull( nameof( createFunctionality ), createFunctionali
 307         this._extractStreamOnConnectionAcquirementError = ArgumentValidator.ValidateNotNull( nameof( extractStreamOnCon
 308      }
 309
 310      /// <inheritdoc />
 311      protected override ValueTask<TPrivateConnection> CreateConnection( TConnectionFunctionality functionality )
 312         => this._createConnection( functionality );
 313
 314      /// <inheritdoc />
 315      protected override AsyncResourceAcquireInfo<TPrivateConnection> CreateConnectionAcquireInfo( TConnectionFunctional
 316         => this._createConnectionAcquireInfo( functionality, connection );
 317
 318      /// <inheritdoc />
 319      protected override ValueTask<TConnectionFunctionality> CreateFunctionality( BinaryStringPool stringPool, Stream ac
 320         => this._createFunctionality( this.CreationParameters, this.Encoding, stringPool, !ReferenceEquals( this.Global
 321
 322      /// <inheritdoc />
 323      protected override IDisposable ExtractStreamOnConnectionAcquirementError( TConnectionFunctionality functionality, 
 324         => this._extractStreamOnConnectionAcquirementError( functionality, connection, token, error );
 325   }
 326
 327   /// <summary>
 328   /// This callback is used to create intermediate state used throughout various stages of asynchronous remote connecti
 329   /// </summary>
 330   /// <typeparam name="TConnectionCreationParameters">The type of connection cration parameters.</typeparam>
 331   /// <typeparam name="TIntermediateState">The type of the intermediate state.</typeparam>
 332   /// <param name="creationParameters">The connection creation parameters.</param>
 333   /// <param name="encoding">The <see cref="IEncodingInfo"/> used to (de)serialize strings.</param>
 334   /// <param name="stringPool">The <see cref="BinaryStringPool"/> to use when deserializing strings.</param>
 335   /// <param name="stringPoolIsDedicated"><c>true</c> if the <paramref name="stringPool"/> is dedicated to this connect
 336   /// <param name="stream">The <see cref="Stream"/> to the remote endpoint.</param>
 337   /// <param name="socketOrNull">The socket to the remote endpoint, or <c>null</c>, if stream was created via <see cref
 338   /// <param name="token">The <see cref="CancellationToken"/> to use.</param>
 339   /// <returns>An intermediate state to use throughout various stages of asynchronous remote connection initialization.
 340   public delegate TIntermediateState CreateIntermediateStateDelegate<TConnectionCreationParameters, TIntermediateState>
 341      TConnectionCreationParameters creationParameters,
 342      IEncodingInfo encoding,
 343      BinaryStringPool stringPool,
 344      Boolean stringPoolIsDedicated,
 345      Object socketOrNull,
 346      Stream stream,
 347      CancellationToken token
 348      );
 349
 350   /// <summary>
 351   /// This delegate is used to check whether remote end supports SSL, when there is no intermediate state used during c
 352   /// </summary>
 353   /// <typeparam name="TConnectionCreationParameters">The type of connection creation parameters.</typeparam>
 354   /// <typeparam name="TIntermediateState">The type of the intermediate state.</typeparam>
 355   /// <param name="creationParameters">The connection creation parameters.</param>
 356   /// <param name="encoding">The <see cref="IEncodingInfo"/> used to (de)serialize strings.</param>
 357   /// <param name="stringPool">The <see cref="BinaryStringPool"/> to use when deserializing strings.</param>
 358   /// <param name="stringPoolIsDedicated"><c>true</c> if the <paramref name="stringPool"/> is dedicated to this connect
 359   /// <param name="intermediateState">The intermediate state created previously.</param>
 360   /// <returns>Asynchronously checks whether remote endpoint supports using SSL.</returns>
 361   /// <seealso cref="TaskUtils.False"/>
 362   /// <seealso cref="TaskUtils.True"/>
 363   public delegate Task<Boolean> IsSSLPossibleDelegate<TConnectionCreationParameters, TIntermediateState>(
 364      TConnectionCreationParameters creationParameters,
 365      IEncodingInfo encoding,
 366      BinaryStringPool stringPool,
 367      Boolean stringPoolIsDedicated,
 368      TIntermediateState intermediateState
 369      );
 370
 371   /// <summary>
 372   /// This delegate is used to create close-to-protocol connection functionality object.
 373   /// </summary>
 374   /// <typeparam name="TConnectionFunctionality">The type of close-to-protocol connection functionality.</typeparam>
 375   /// <typeparam name="TConnectionCreationParameters">The type of connection cration parameters.</typeparam>
 376   /// <typeparam name="TIntermediateState">The type of the intermediate state.</typeparam>
 377   /// <param name="creationParameters">The connection creation parameters.</param>
 378   /// <param name="encoding">The <see cref="IEncodingInfo"/> used to (de)serialize strings.</param>
 379   /// <param name="stringPool">The <see cref="BinaryStringPool"/> to use when deserializing strings.</param>
 380   /// <param name="stringPoolIsDedicated"><c>true</c> if the <paramref name="stringPool"/> is dedicated to this connect
 381   /// <param name="stream">The <see cref="Stream"/> to the remote endpoint.</param>
 382   /// <param name="socketOrNull">The socket to the remote endpoint, or <c>null</c>, if stream was created via <see cref
 383   /// <param name="token">The <see cref="CancellationToken"/> to use.</param>
 384   /// <param name="intermediateState">The intermediate state created previously.</param>
 385   /// <returns>Potentially asynchronously creates the close-to-protocol connection functionality object.</returns>
 386   public delegate ValueTask<TConnectionFunctionality> CreateConnectionFunctionality<TConnectionFunctionality, TIntermed
 387      TConnectionCreationParameters creationParameters,
 388      IEncodingInfo encoding,
 389      BinaryStringPool stringPool,
 390      Boolean stringPoolIsDedicated,
 391      Stream stream,
 392      Object socketOrNull,
 393      CancellationToken token,
 394      TIntermediateState intermediateState
 395      );
 396
 397}