在约束上下文中执行代码

如果你希望在特定(约束)上下文下执行代码( 例程 ),则可以使用依赖项注入。

以下示例显示了在开放 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() 子句,你永远不会知道例程是否会破坏上下文的约束来处置这些资源。