在約束上下文中執行程式碼

如果你希望在特定(約束)上下文下執行程式碼( 例程 ),則可以使用依賴項注入。

以下示例顯示了在開放 SSL 連線下執行的約束。第一部分將在你的庫或框架中,你不會將其暴露給客戶端程式碼。

public static class SSLContext
{
    // define the delegate to inject
    public delegate void TunnelRoutine(BinaryReader sslReader, BinaryWriter sslWriter);

    // this allows the routine to be executed under SSL
    public static void ClientTunnel(TcpClient tcpClient, TunnelRoutine routine)
    {
        using (SslStream sslStream = new SslStream(tcpClient.GetStream(), true, _validate))
        {
            sslStream.AuthenticateAsClient(HOSTNAME, null, SslProtocols.Tls, false);

            if (!sslStream.IsAuthenticated)
            {
                throw new SecurityException("SSL tunnel not authenticated");
            }

            if (!sslStream.IsEncrypted)
            {
                throw new SecurityException("SSL tunnel not encrypted");
            }

            using (BinaryReader sslReader = new BinaryReader(sslStream))
            using (BinaryWriter sslWriter = new BinaryWriter(sslStream))
            {
                routine(sslReader, sslWriter);
            }
        }
    }
}

現在客戶端程式碼想要在 SSL 下執行某些操作但不想處理所有 SSL 詳細資訊。你現在可以在 SSL 隧道內執行任何操作,例如交換對稱金鑰:

public void ExchangeSymmetricKey(BinaryReader sslReader, BinaryWriter sslWriter)
{
    byte[] bytes = new byte[8];
    (new RNGCryptoServiceProvider()).GetNonZeroBytes(bytes);
    sslWriter.Write(BitConverter.ToUInt64(bytes, 0));
}

你執行此例程如下:

SSLContext.ClientTunnel(tcpClient, this.ExchangeSymmetricKey);

要做到這一點,你需要 using() 子句,因為它是唯一的方法(除了 try..finally 塊)你可以保證客戶端程式碼(ExchangeSymmetricKey)永遠不會在沒有正確處理可支配資源的情況下退出。如果沒有 using() 子句,你永遠不會知道例程是否會破壞上下文的約束來處置這些資源。