Vieta chiamate a funzioni / classi arbitrarie in codice esterno


12

Ho riscontrato casi in cui sarebbe utile limitare l'accesso all'API di librerie e framework esterni per prevenire conseguenze negative nel sistema.

Ad esempio, in un'applicazione SharePoint può sembrare naturale chiamare spList.Items.GetItemByIdper ottenere un elemento dell'elenco, anche forse in un ciclo, senza rendersi conto che ciò può portare a enormi problemi di prestazioni.

Potrebbe anche essere necessario vietare l'utilizzo di SmtpClient per costringere tutti a utilizzare la nostra classe per inviare e-mail, per garantire che possiamo eseguire correttamente il proxy e deridere tutte le e-mail quando ci troviamo nell'ambiente di test.

Esistono modi affidabili e ragionevolmente semplici per raggiungere questi vincoli sul codice esterno, ad eccezione di determinati punti specifici del nostro codice? Non è assolutamente necessario in ogni circostanza impedire l'accesso a questi metodi / classi, ad esempio tramite la riflessione o semplicemente una sorta di disabilitazione, dovrebbe piuttosto essere un avvertimento rigoroso che non dovrebbero essere utilizzati. Preferibilmente costringendo il programmatore ad adottare attivamente misure per superare questi vincoli se possibile / necessario.


11
Sembra una forzatura di una forma estrema di stile di codifica (Vietato usare una particolare chiamata in biblioteca). Quindi per me solleva la domanda preliminare di fare qualche revisione del codice, o controlli di stile in primo luogo?
Peter M,

3
Speri di intercettare e bloccare queste chiamate in fase di runtime o di compilazione ?
MetaFight,

1
Da quando usi C #, hai mai sentito parlare di StyleCop ? Sai che puoi creare regole personalizzate come preferisci, giusto?
Machado,

10
" Esistono modi affidabili e ragionevolmente semplici per raggiungere questi vincoli sul codice esterno, ad eccezione di determinati punti specifici del nostro codice? ". Sì: scrivi il tuo analizzatore Roslyn per segnalare l'accesso a determinate API come errore di compilazione.
David Arno,

3
@Machado, StyleCop è effettivamente un prodotto morto. Viene sostituito con StyleCopAnalyzers, che si basa su Roslyn. Al giorno d'oggi non sarebbe una buona idea investire tempo nello scrivere regole StyleCop personalizzate.
David Arno,

Risposte:


8

Esistono modi affidabili e ragionevolmente semplici per raggiungere questi vincoli sul codice esterno, ad eccezione di determinati punti specifici del nostro codice?

Poiché la domanda riguarda specificamente C #, esiste una soluzione basata su compilatore che può essere utilizzata qui per applicare tali regole: Roslyn Analyzers . È possibile scrivere il proprio analizzatore che segnala l'accesso a determinate API come errore di compilazione o avviso.

Un esempio di analizzatori, che forniscono un sacco di codice di esempio per scrivere i propri, sono gli analizzatori StyleCop , che sostituiscono la vecchia funzionalità StyleCop per C #.

Detto questo, tali controlli automatizzati possono sempre essere aggirati da persone determinate a "infrangere le regole". Pertanto questo approccio non sostituisce le revisioni del codice, come discusso nella risposta di Karl Bielefeldt. Può aiutare con tali revisioni, ma non dovrebbe sostituirle.


Non è mai stata intenzione di sostituire nient'altro, ero solo alla ricerca di uno strumento specializzato per la mia cassetta degli attrezzi.
Alex,

25

Puoi fare cose che richiedono molto tempo come scrivere un wrapper attorno all'API esterna che elimina le operazioni indesiderate, ma nulla è meglio di formazione e revisioni del codice, perché qualsiasi standard o misura tecnica tu abbia messo in atto, le persone troveranno modi creativi per aggirarle .

Ad esempio, abbiamo scritto diversi servizi in Scala, e una delle cose che chiediamo al momento della revisione del codice è l'immutabilità, ma spesso lo comunichiamo come sbarazzarci di vars. Qualcuno l'altro giorno ha usato un val x: ListBuffer [Boolean] per contenere una singola variabile mutabile come unico elemento nell'elenco. Non puoi assegnarne un altro ListBuffera x, ma puoi sostituire gli elementi dell'elenco nella posizione desiderata. Cattivo come usare un var, ma più subdolo.

In altre parole, devi verificare se le persone stanno aggirando le tue soluzioni tecniche. Se queste soluzioni tecniche sono costose e aggiungono complessità, puoi anche controllare che lo stiano codificando correttamente.


accidenti che è subdolo!
quando l'

@snb È equivalente a ciò che Java fa come hack per aggirare solo la possibilità di restituire un oggetto / valore e non avere argomenti di riferimento adeguati; passando invece un array che avrà i suoi contenuti aggiornati. (Alcuni esempi: AtomicMarkableReference.gete AtomicStampedReference.get).
JAB

Grazie per la risposta, ma non sono assolutamente interessato a fare cose complesse che richiedono molto tempo come scrivere wrapper attorno al codice esterno. Probabilmente non sarebbe nemmeno d'aiuto dato che possono semplicemente andare alla fonte. Questa risposta sembra presumere che una soluzione sarà costosa e aggiungerà complessità. Che dire di una soluzione pura e semplice?
Alex,

1
@Alex la soluzione più semplice è proprio lì: "niente è meglio di training e revisioni del codice".
Mr.Mindor,

2
"niente è meglio di farlo manualmente" è giusto finché qualcuno non lo automatizza.
Ewan,

0

La risposta di Karl è corretta al 100%. Non c'è modo di garantire la conformità. Tuttavia, oltre alla formazione e alle revisioni del codice, prendere in considerazione l'uso di strumenti di analisi statica per garantire la conformità. (Nota: ho detto "oltre a", in quanto si possono bypassare anche quelli esattamente nello stesso modo in cui ha dichiarato Karl).

Il vantaggio di utilizzare strumenti di analisi statica è quello di rimuovere noiose analisi del codice umano alla ricerca di istanze di "uso multiplo di IEnumerable" o di qualsiasi problema di prestazioni della settimana che stai guardando (o, almeno, che sento sempre di essere guardando). Ciò consentirà alle revisioni del codice e alla formazione di concentrarsi su questioni più "interessanti".

Per C #, in particolare, ho incluso alcuni suggerimenti di seguito. Collegali al tuo ambiente di costruzione e sei a posto. Ma, generalmente, non importa quale lingua stai usando, c'è uno strumento di analisi statica là fuori da qualche parte.

Copia / incolla direttamente dalla pagina Wikipedia, utilizza la pagina wiki per le informazioni e i collegamenti più recenti: https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis#.NET

  • Piattaforma di compilazione .NET (nome in codice Roslyn) - Framework di compilazione open source per C # e Visual Basic .NET sviluppato da Microsoft .NET. Fornisce un'API per l'analisi e la manipolazione della sintassi.
  • CodeIt.Right: combina l'analisi del codice statico e il refactoring automatico con le migliori pratiche che consentono la correzione automatica di errori e violazioni del codice; supporta C # e VB.NET.
  • CodeRush - Un plug-in per Visual Studio che avvisa gli utenti di violazioni delle migliori pratiche.
  • FxCop - Analisi statica gratuita per i programmi Microsoft .NET che vengono compilati in CIL. Autonomo e integrato in alcune edizioni di Microsoft Visual Studio; da Microsoft.
  • NDepend: semplifica la gestione di una base di codice .NET complessa analizzando e visualizzando le dipendenze del codice, definendo le regole di progettazione, eseguendo l'analisi dell'impatto e confrontando diverse versioni del codice. Si integra in Visual Studio.
  • Parasoft dotTEST - Un plug-in per l'analisi statica, il test dell'unità e la revisione del codice per Visual Studio; funziona con i linguaggi per Microsoft .NET Framework e .NET Compact Framework, inclusi C #, VB.NET, ASP.NET e Managed C ++.
  • Sonargraph: supporta C #, Java e C / C ++ con particolare attenzione all'analisi delle dipendenze, al controllo automatizzato dell'architettura, alle metriche e alla possibilità di aggiungere metriche personalizzate e controlli del codice.
  • StyleCop: analizza il codice sorgente C # per applicare un insieme di regole di stile e coerenza. Può essere eseguito dall'interno di Microsoft Visual Studio o integrato in un progetto MSBuild.

-1

Per approfondire il suggerimento di "formazione e revisione del codice" sollevato in un'altra risposta: poiché il codice che desideri vietare è un codice legale, non puoi fare affidamento sul compilatore che lo impedisce e dovrai fare affidamento su un processo successivo, la recensione.

Questo può (e dovrebbe) includere passaggi di revisione sia manuali che automatici:

  • Prepara un elenco di controllo dei problemi noti e analizzali uno alla volta nelle recensioni del codice manuale. Avere una riunione ricorrente per rivedere e aggiornare l'elenco di controllo. Ogni volta che viene catturato e analizzato un brutto bug, aggiungilo alla lista di controllo.

  • Aggiungi le regole di check-in per cercare modelli noti. Questo può essere complicato da scrivere, ma per un grande progetto, nel tempo, può essere utile. TFS ti consente di scrivere regole in C # e altri sistemi di build hanno i loro hook. Prendi in considerazione l'utilizzo di build gated per rifiutare i check-in che corrispondono allo schema. Sì, rallenta lo sviluppo, ma dopo una certa dimensione e complessità del progetto, rallentare gli sviluppatori può essere una buona cosa.


-1

Forse il compilatore può aiutarti a catturare chiamate indesiderate.

Rinominare le classi / i metodi di codice nella propria lib che non devono essere usati da client lib esterni. In alternativa, rendere le classi / i metodi interni e aggiungere gli interni visibili a quelle classi che sono autorizzati a usarli.

Gli utenti esterni di lib riceveranno un metodo / classe di errore di compilazione non trovato.

Classi / metodi proibiti dalle librerie pubbliche: crea lo stesso spazio dei nomi / classe / metodo nella tua libreria

Gli utenti esterni di lib riceveranno un errore di compilazione a causa della presenza di una classe duplicata

[aggiornare]

Non è assolutamente necessario in ogni circostanza impedire l'accesso a questi metodi / classi, ad esempio tramite la riflessione o semplicemente una sorta di disabilitazione, ....

costringere il programmatore (... client della lib ...) ad adottare attivamente misure per superare questi vincoli se possibile / necessario.


Downvoting questo, non solo perché è un brutto hack, ma è facilmente aggirabile con C # (con cui l'OP ha taggato la domanda) usando alias esterni .
David Arno,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.