Novidades do C# 12: Interceptors

Renato Groffe
4 min readOct 9, 2023

--

Neste artigo da série sobre novidades do C# 12 abordo o uso de Interceptors, um recurso considerado até o presente momento (início de Outubro/2023) como experimental. Pretendo publicar eventualmente um novo post a respeito de Interceptors, caso esta funcionalidade passe por alterações futuras (algo bastante provável).

Um Interceptor é implementado como um método que permite interceptar a chamada a um outro método em um ponto qualquer de uma aplicação, sobrepondo ou mesmo complementando o resultado/comportamento da funcionalidade invocada originalmente.

Considerando a classe EnvironmentVariablesHelper, com o método ShowContent que exibirá o conteúdo de uma variável de ambiente:

E o código de Program.cs, correspondente a uma Console Application e que emprega este tipo (EnvironmentVariablesHelper) para exibir informações sobre a IDE em uso:

Ao executarmos essa aplicação a partir do Visual Studio 2022 teremos um resultado similar ao seguinte:

Clique nesta imagem para visualizar com uma melhor resolução

Através da utilização de Interceptors poderíamos capturar/interceptar chamadas a Console.WriteLine, incluindo conteúdos adicionais às mensagens originais exibidas em tela (ou mesmo substituindo estas). Na imagem a seguir (uma variação do exemplo apresentado na figura anterior) estão destacadas em vermelho alterações produzidas por métodos de interceptação:

Clique nesta imagem para visualizar com uma melhor resolução

O código original mostrado nas 2 listagens anteriores permaneceria inclusive inalterado, com este novo recurso representando uma interessante forma de estender implementações pré-existentes.

Por se tratar de um recurso ainda experimental, precisei criar a seguinte implementação de InterceptsLocationAttribute, um tipo previsto para integrar o namespace System.Runtime.CompilerServices:

Esta solução pouco convencional foi inclusive apresentada em uma discussão que encontrei no site Stack Overflow (clique neste link para ter acesso à mesma).

Já a classe InterceptorConsoleApp possui a definição de métodos estáticos que foram marcados com InterceptsLocationAttribute:

  • Cada um desses 3 métodos (InterceptorMethodBegin, InterceptorMethodEnvVar e InterceptorMethodEnd) intercepta uma ocorrência de Console.WriteLine ao longo da Console Application (duas em Program.cs, uma em EnvironmentVariablesHelper.cs);
  • No atributo InterceptsLocation também devem ser indicados a linha em que está o método a ser interceptado, assim como a partir de qual caracter/coluna está o nome de tal método;
  • A assinatura de um método de interceptação deve coincidir com aquela correspondente ao método interceptado. Assim como Console.WriteLine, InterceptorMethodBegin, InterceptorMethodEnvVar e InterceptorMethodEnd recebem como parâmetro uma string (mantendo a assinatura do método original) e ainda acrescentam conteúdos em texto no início das mensagens (reinvocando Console.WriteLine).

O método InterceptorMethodBegin em InterceptorConsoleApp está marcado com InterceptsLocation:

E aponta para a chamada ao método WriteLine da classe Console em Program.cs na linha 4, coluna 9:

Clique nesta imagem para visualizar com uma melhor resolução

Temos então o método InterceptorMethodEnvVar:

Interceptando a chamada a WriteLine na linha 7, coluna 17 de EnvironmentVariablesHelper (método ShowContent):

Clique nesta imagem para visualizar com uma melhor resolução

Finalmente chegamos ao método InterceptorMethodEnd:

Que irá capturar a chamada a WriteLine em Program.cs na linha 16, coluna/caracter 9:

Clique nesta imagem para visualizar com uma melhor resolução

O arquivo .csproj também deverá ser alterado. Além do valor preview em LangVersion, o atributo Features foi configurado com o valor InterceptorsPreview:

Na próxima imagem temos o resultado da execução desta aplicação a partir do Visual Studio 2022, já considerando o uso de Interceptors:

Clique nesta imagem para visualizar com uma melhor resolução

A estrutura deste projeto de exemplo utilizando Interceptors pode ser observada na próxima imagem:

Clique nesta imagem para visualizar com uma melhor resolução

O código deste exemplo foi disponibilizado no GitHub:

https://github.com/renatogroffe/CSharp12-Interceptors-DotNet8_RC1

Caso achem útil esta solução, peço por favor um ⭐️ no repositório apoiando. Fica também o convite para que vocês me sigam lá no GitHub!

E termino este artigo com mais um convite…

Acompanhe neste novo evento ONLINE e GRATUITO no Canal .NET dicas, truques e alternativas úteis para o desenvolvimento Back-End e de APIs REST com .NET 7, C#, ASP.NET Core e Azure Functions. Ao longo da apresentação será abordado o uso de diferentes frameworks, serviços na nuvem, mensageria e boas práticas de forma a facilitar e tornar mais dinâmica a implementação de soluções baseadas na plataforma .NET no seu dia a dia.

Teremos ainda novidades do .NET 8 e C# 12 demonstradas através de exemplos práticos!

Quando: 16/10/2023 (segunda) a partir das 21:00 — horário de Brasília

Faça sua inscrição em:
https://www.meetup.com/dotnet-sao-paulo/events/295621042/

--

--

Renato Groffe
Renato Groffe

Written by Renato Groffe

Microsoft Most Valuable Professional (MVP), Multi-Plataform Technical Audience Contributor (MTAC), Software Engineer, Technical Writer and Speaker