Eu experimentei casos em que seria valioso restringir o acesso à API de bibliotecas e estruturas externas para evitar consequências negativas no sistema.
Por exemplo, em um aplicativo do SharePoint, pode parecer natural chamar spList.Items.GetItemById
para obter um item da lista, mesmo que seja em um loop, sem perceber que isso pode levar a enormes problemas de desempenho.
Também é possível que precisamos proibir o uso do SmtpClient para forçar todos a usar nossa própria classe para enviar email, para garantir que possamos proxy e zombar adequadamente de todos os emails no ambiente de teste.
Existem maneiras confiáveis e razoavelmente diretas de obter essas restrições no código externo, exceto em determinados locais específicos do nosso próprio código? Não é necessário absolutamente sob todas as circunstâncias impedir o acesso a esses métodos / classes, por exemplo, por reflexão ou apenas algum tipo de desativação, deve ser um aviso estrito de que eles não devem ser usados. De preferência, forçando o programador a tomar ativamente medidas para substituir essas restrições, se possível / necessário.
fonte
Respostas:
Como a pergunta é especificamente sobre C #, existe uma solução baseada em compilador que pode ser usada aqui para impor essas regras: Roslyn Analyzers . Você pode escrever seu próprio analisador que relata o acesso a determinadas APIs como um erro ou aviso de compilação.
Um exemplo de conjunto de analisadores, que fornecem muitos códigos de exemplo ao escrever seus próprios, são os analisadores StyleCop , que substituem o antigo recurso StyleCop do C #.
Dito isto, essas verificações automatizadas sempre podem ser contornadas por pessoas determinadas a "violar as regras". Portanto, essa abordagem não substitui as revisões de código, conforme discutido na resposta de Karl Bielefeldt. Pode ajudar com essas revisões, mas não deve substituí-las.
fonte
Você pode fazer coisas demoradas, como escrever um invólucro em torno da API externa que exclui suas operações indesejadas, mas nada supera as análises de treinamento e de código, porque, independentemente dos padrões ou medidas técnicas que você colocar em prática, as pessoas encontrarão maneiras criativas de contorná-las .
Por exemplo, temos vários serviços escritos em Scala, e uma das coisas que pedimos no momento da revisão de código é a imutabilidade, mas geralmente o comunicamos como se livrar do
vars
. Alguém no outro dia usou um val x: ListBuffer [Boolean] para armazenar uma única variável mutável como o único item da lista. Você não pode atribuir outroListBuffer
para x, mas pode substituir os itens da lista no local o quanto quiser. Tão ruim quanto usar umvar
, mas mais furtivo.Em outras palavras, você deve verificar se as pessoas estão contornando suas soluções técnicas. Se essas soluções técnicas são caras e aumentam a complexidade, você também pode apenas verificar se elas estão codificando corretamente.
fonte
AtomicMarkableReference.get
eAtomicStampedReference.get
).A resposta de Karl está 100% correta. Não há como garantir a conformidade. No entanto, além das revisões de treinamento e código, considere o uso de ferramentas de análise estática para garantir a conformidade. (Nota: eu disse "além de", pois é possível contorná-las exatamente da mesma maneira que Karl afirmou).
A vantagem de usar ferramentas de análise estática é remover a tediosa análise de código humano, procurando instâncias de "uso múltiplo de IEnumerable" ou qualquer problema de desempenho da semana em que você está olhando (ou, pelo menos, que eu sempre sinto que estou olhando para). Isso permitirá que as revisões e o treinamento do código se concentrem em questões mais "interessantes".
Para C #, especificamente, incluí algumas sugestões abaixo. Conecte-os ao seu ambiente de construção e pronto. Mas, geralmente, não importa qual idioma você esteja usando, há uma ferramenta de análise estática disponível em algum lugar.
Copie / cole diretamente da página da Wikipedia, use a página da wiki para obter as informações e links mais recentes: https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis#.NET
fonte
Para elaborar a sugestão "treinamento e revisão de código" apresentada em outra resposta: como o código que você deseja proibir é o código legal, você não pode contar com o compilador que o impede e precisará confiar em um processo posterior, A revisão.
Isso pode (e deve) incluir etapas de revisão manual e automática:
Prepare uma lista de verificação de problemas conhecidos e repasse-os em suas revisões de código manuais, uma por uma. Tenha uma reunião recorrente para revisar e atualizar a lista de verificação. Sempre que um bug desagradável for detectado e analisado, adicione-o à lista de verificação.
Adicione regras de check-in para procurar padrões conhecidos. Isso pode ser complicado de escrever, mas para um projeto grande, com o tempo, pode ser útil. O TFS permite escrever regras em C #, e outros sistemas de construção têm seus próprios ganchos. Considere usar construções fechadas para rejeitar check-ins que correspondem ao padrão. Sim, atrasa o desenvolvimento, mas após um certo tamanho e complexidade do projeto, desacelerar os desenvolvedores pode ser uma coisa boa.
fonte
Talvez o compilador possa ajudá-lo a capturar chamadas indesejadas.
Renomeie as classes / métodos de código em sua própria lib que não devem ser usados por clientes externos da lib. Alternativamente, torne as classes / métodos internos e adicione internos visíveis para as classes que têm permissão para usá-los.
Usuários de bibliotecas externas obterão um método / classe de erro de compilação não encontrado.
Classes / métodos proibidos de bibliotecas públicas: crie o mesmo espaço para nome / classe / método em sua biblioteca
Usuários de bibliotecas externas receberão um erro de compilação devido à classe duplicada encontrada
[atualizar]
fonte