Repository: microsoft/semantic-kernel
File: dotnet/samples/Concepts/ChatCompletion/HybridCompletion_Fallback.cs (C#)

Code before:
        AzureOpenAIPromptExecutionSettings settings = new()
        {
            FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
        };

        IAsyncEnumerable<StreamingChatMessageContent> result = fallbackCompletionService.GetStreamingChatMessageContentsAsync("Do I need an umbrella?", settings, kernel);

        await foreach (var update in result)
        {
            Output.WriteLine(update);
        }
    }

    private static IChatClient CreateUnavailableOpenAIChatClient()
    {
        AzureOpenAIClientOptions options = new()
        {
            Transport = new HttpClientPipelineTransport(
                new HttpClient
                (
                    new StubHandler(new HttpClientHandler(), async (response) => { response.StatusCode = System.Net.HttpStatusCode.ServiceUnavailable; })
                )
            )
        };

        IChatClient openAiClient = new AzureOpenAIClient(new Uri(TestConfiguration.AzureOpenAI.Endpoint), new AzureCliCredential(), options).AsChatClient(TestConfiguration.AzureOpenAI.ChatDeploymentName);

        return new ChatClientBuilder(openAiClient)
            .UseFunctionInvocation()
            .Build();
    }

    private static IChatClient CreateAzureOpenAIChatClient()
    {
        IChatClient chatClient = new AzureOpenAIClient(new Uri(TestConfiguration.AzureOpenAI.Endpoint), new AzureCliCredential()).AsChatClient(TestConfiguration.AzureOpenAI.ChatDeploymentName);

        return new ChatClientBuilder(chatClient)
            .UseFunctionInvocation()
            .Build();
    }

    protected sealed class StubHandler(HttpMessageHandler innerHandler, Func<HttpResponseMessage, Task> handler) : DelegatingHandler(innerHandler)
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var result = await base.SendAsync(request, cancellationToken);

            await handler(result);

            return result;
        }

Review comment (suggestion):
Maybe the names don't reflect what's happening here, but doesn't `GetChatClient` return a `ChatClient` that implements `IChatClient`?  It seems funny that we are saying `GetChatClient` and then `AsIChatClent`...

Code after:
        AzureOpenAIPromptExecutionSettings settings = new()
        {
            FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
        };

        IAsyncEnumerable<StreamingChatMessageContent> result = fallbackCompletionService.GetStreamingChatMessageContentsAsync("Do I need an umbrella?", settings, kernel);

        await foreach (var update in result)
        {
            Output.WriteLine(update);
        }
    }

    private static IChatClient CreateUnavailableOpenAIChatClient()
    {
        AzureOpenAIClientOptions options = new()
        {
            Transport = new HttpClientPipelineTransport(
                new HttpClient
                (
                    new StubHandler(new HttpClientHandler(), async (response) => { response.StatusCode = System.Net.HttpStatusCode.ServiceUnavailable; })
                )
            )
        };

        IChatClient openAiClient = new AzureOpenAIClient(new Uri(TestConfiguration.AzureOpenAI.Endpoint), new AzureCliCredential(), options).GetChatClient(TestConfiguration.AzureOpenAI.ChatDeploymentName).AsIChatClient();

        return new ChatClientBuilder(openAiClient)
            .UseFunctionInvocation()
            .Build();
    }

    private static IChatClient CreateAzureOpenAIChatClient()
    {
        IChatClient chatClient = new AzureOpenAIClient(new Uri(TestConfiguration.AzureOpenAI.Endpoint), new AzureCliCredential()).GetChatClient(TestConfiguration.AzureOpenAI.ChatDeploymentName).AsIChatClient();

        return new ChatClientBuilder(chatClient)
            .UseFunctionInvocation()
            .Build();
    }

    protected sealed class StubHandler(HttpMessageHandler innerHandler, Func<HttpResponseMessage, Task> handler) : DelegatingHandler(innerHandler)
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var result = await base.SendAsync(request, cancellationToken);

            await handler(result);

            return result;
        }