Nosso software possui várias classes que devem ser encontradas dinamicamente via reflexão. Todas as classes têm um construtor com uma assinatura específica através da qual o código de reflexão instancia objetos.
No entanto, quando alguém verifica se o método é referenciado (por exemplo, através do Visual studio Code Lens), a referência via reflexão não é contada. As pessoas podem perder suas referências e remover (ou alterar) métodos aparentemente não utilizados.
Como devemos marcar / documentar métodos destinados a serem chamados via reflexão?
Idealmente, o método deve ser marcado de forma que os colegas e o Visual Studio / Roslyn e outras ferramentas automatizadas 'vejam' que o método deve ser chamado por meio de reflexão.
Conheço duas opções que podemos usar, mas ambas não são satisfatórias. Como o Visual Studio não pode encontrar as referências:
- Use um atributo personalizado e marque o construtor com este atributo.
- Um problema é que as propriedades do Atributo não podem ser uma referência de método, portanto, o construtor ainda será exibido como tendo 0 referências.
- Os colegas que não estão familiarizados com o atributo personalizado provavelmente o ignorarão.
- Uma vantagem da minha abordagem atual é que a parte de reflexão pode usar o atributo para encontrar o construtor que deve chamar.
- Use comentários para documentar que um método / construtor deve ser chamado por meio de reflexão.
- As ferramentas automatizadas ignoram os comentários (e os colegas também podem fazê-lo).
- Os comentários da documentação Xml podem ser usados para que o Visual Studio conte uma referência adicional ao método / construtor:
SejaMyPlugin
a classe cujo construtor deve chamar por meio de reflexão. Suponha que o código de reflexão de chamada procure por construtores que usam umint
parâmetro. A documentação a seguir faz com que essa lente de código mostre o construtor com 1 referência:
/// <see cref="MyPlugin.MyPlugin(int)"/> is invoked via reflection
Que melhores opções existem?
Qual é a melhor prática para marcar um método / construtor que se pretende chamar por reflexão?
fonte
Respostas:
Uma combinação das soluções sugeridas:
Isso deve esclarecer o uso pretendido para os colegas (e meu futuro eu).
<see>
-tag para aumentar a contagem de referência para o construtor / método.Isso faz com que essa lente de código e as referências de localização mostrem que o construtor / método é referenciado.
UsedImplicitlyAttribute
[UsedImplicitly]
possui precisamente a semântica pretendida.PM>
Install-Package JetBrains.Annotations
.SupressMessageAttribute
para a mensagemCA1811: Avoid uncalled private code
.Por exemplo:
A solução confere o uso pretendido do construtor aos leitores humanos e aos 3 sistemas de análise de código estático mais usados com C # e Visual Studio.
A desvantagem é que tanto um comentário quanto uma ou duas anotações podem parecer um pouco redundantes.
fonte
MeansImplicitUseAttribute
que pode ser usado para criar seus próprios atributos que têmUsedImplicitly
efeito. Isso pode reduzir muito ruído de atributo nas situações certas.Nunca tive esse problema em um projeto .Net, mas regularmente tenho o mesmo problema em projetos Java. Minha abordagem usual é usar a
@SuppressWarnings("unused")
anotação adicionando um comentário explicando o motivo (documentar o motivo da desativação de qualquer aviso faz parte do meu estilo de código padrão - sempre que o compilador não conseguir descobrir algo, presumo que é provável que um humano possa ter problemas também). Isso tem a vantagem de garantir automaticamente que as ferramentas de análise estática estejam cientes de que o código não deve ter referências diretas e fornecer um motivo detalhado para os leitores humanos.O equivalente em C # de Java
@SuppressWarnings
éSuppressMessageAttribute
. Para métodos particulares , você pode usar a mensagem CA1811: Evite código privado desnecessário ; por exemplo:fonte
SuppressMessageAttribute
( msdn.microsoft.com/en-us/library/… ). A mensagem mais próxima éCA1811: Avoid uncalled private code
( msdn.microsoft.com/en-us/library/ms182264.aspx ); Ainda não encontrei uma mensagem para código público.Uma alternativa à documentação seria ter testes de unidade, certificando-se de que as chamadas de reflexão sejam executadas com êxito.
Dessa forma, se alguém alterar ou remover os métodos, seu processo de construção / teste deve alertá-lo de que você quebrou alguma coisa.
fonte
Bem, sem ver seu código, parece que esse seria um bom lugar para introduzir alguma herança. Talvez um método virtual ou abstrato que o construtor dessas classes possa chamar? Se você é o método que você está tentando marcar é apenas o construtor, então você está realmente tentando marcar uma classe e não um método, sim? Algo que eu fiz no passado para marcar classes é criar uma interface vazia. Em seguida, as ferramentas de inspeção de código e a refatoração podem procurar classes que implementam a interface.
fonte