He experimentado casos en los que sería valioso restringir el acceso a la API de bibliotecas y marcos externos para evitar consecuencias negativas en el sistema.
Por ejemplo, en una aplicación de SharePoint puede parecer natural llamar spList.Items.GetItemById
para obtener un elemento de la lista, incluso tal vez en un bucle, sin darse cuenta de que esto puede conducir a grandes problemas de rendimiento.
También podría ser que debamos prohibir el uso de SmtpClient para obligar a todos a usar nuestra propia clase para enviar correos electrónicos, para asegurarnos de que podamos usar proxy y burlarnos de todos los correos electrónicos en el entorno de prueba.
¿Hay alguna forma confiable y razonablemente directa de lograr estas restricciones en el código externo, excepto desde ciertos lugares específicos en nuestro propio código? No es necesario, bajo ninguna circunstancia, impedir el acceso a estos métodos / clases, por ejemplo, por reflexión o simplemente por algún tipo de deshabilitación, más bien debería ser una advertencia estricta de que no deberían usarse. Preferiblemente, forzar al programador a tomar medidas activas para anular estas restricciones si es posible / necesario.
Respuestas:
Como la pregunta es específicamente sobre C #, hay una solución basada en compilador que se puede usar aquí para hacer cumplir tales reglas: Roslyn Analyzers . Podría escribir su propio analizador que informa que accede a ciertas API como un error de compilación o advertencia.
Un conjunto de ejemplos de analizadores, que proporcionan muchos códigos de ejemplo al escribir el suyo, son los analizadores StyleCop , que son un reemplazo de la antigua función StyleCop para C #.
Dicho esto, tales controles automáticos siempre pueden ser solucionados por personas decididas a "romper las reglas". Por lo tanto, este enfoque no es un sustituto de las revisiones de código como se discutió en la respuesta de Karl Bielefeldt. Puede ayudar con tales revisiones, pero no debe reemplazarlas.
fuente
Puede hacer cosas que requieren mucho tiempo, como escribir un contenedor alrededor de la API externa que omita sus operaciones no deseadas, pero nada supera la capacitación y las revisiones de código, porque cualquiera que sea el estándar o las medidas técnicas que implemente, las personas encontrarán formas creativas de sortearlas. .
Por ejemplo, tenemos varios servicios escritos en Scala, y una de las cosas que pedimos en el momento de la revisión del código es la inmutabilidad, pero a menudo lo comunicamos como deshacerse de él
vars
. Alguien el otro día usó un val x: ListBuffer [Boolean] para mantener una sola variable mutable como el único elemento en la lista. No puede asignar otroListBuffer
a x, pero puede reemplazar los elementos de la lista en su lugar tanto como desee. Tan malo como usar unvar
, pero más astuto.En otras palabras, debe verificar si las personas están analizando sus soluciones técnicas. Si esas soluciones técnicas son costosas y agregan complejidad, también puede verificar que lo estén codificando correctamente.
fuente
AtomicMarkableReference.get
yAtomicStampedReference.get
).La respuesta de Karl es 100% correcta. No hay forma de garantizar la conformidad. Sin embargo, además de la capacitación y las revisiones de código, considere el uso de herramientas de análisis estático para garantizar el cumplimiento. (Nota: dije "además de", ya que también se pueden omitir exactamente de la misma manera que Karl declaró).
La ventaja de usar herramientas de análisis estático es la de eliminar el tedioso análisis de código humano en busca de casos de "uso múltiple de IEnumerable" o cualquier problema de rendimiento de la semana que esté viendo (o, al menos, siempre siento que estoy mirando a). Esto permitirá que las revisiones y la capacitación del código se centren en temas más "interesantes".
Para C #, específicamente, he incluido algunas sugerencias a continuación. Conéctelos a su entorno de compilación y listo. Pero, en general, no importa qué idioma esté usando, hay una herramienta de análisis estático en alguna parte.
Copie / pegue directamente desde la página de Wikipedia, use la página wiki para obtener la información y los enlaces más recientes: https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis#.NET
fuente
Para ampliar la sugerencia de "capacitación y revisión de código" planteada en otra respuesta: dado que el código que desea prohibir es el código legal, no puede contar con que el compilador lo impida, y tendrá que confiar en un proceso posterior, La revisión.
Esto puede (y debe) incluir pasos de revisión manual y automática:
Prepare una lista de verificación de problemas conocidos y revísela en sus revisiones de código manuales, una por una. Tenga una reunión periódica para revisar y actualizar la lista de verificación. Siempre que se detecte y analice un error desagradable, agréguelo a la lista de verificación.
Agregue reglas de verificación para buscar patrones conocidos. Esto puede ser complicado de escribir, pero para un proyecto grande, con el tiempo, puede ser útil. TFS le permite escribir reglas en C #, y otros sistemas de compilación tienen sus propios ganchos. Considere usar compilaciones cerradas para rechazar registros que coincidan con el patrón. Sí, ralentiza el desarrollo, pero después de un cierto tamaño y complejidad del proyecto, reducir la velocidad de los desarrolladores puede ser algo bueno.
fuente
Quizás el compilador pueda ayudarlo a capturar llamadas no deseadas.
Cambie el nombre de las clases / métodos de código en su propia biblioteca que no deberían ser utilizados por clientes externos de la biblioteca. Alternativamente, haga que las clases / métodos sean internos y agregue elementos internos visibles para aquellas clases que pueden usarlos.
Los usuarios externos de lib obtendrán un método / clase de error de compilación no encontrado.
Clases / métodos prohibidos de las bibliotecas públicas: cree el mismo espacio de nombres / clase / método en su biblioteca
Los usuarios de lib externos obtendrán un error de compilación debido a la clase duplicada encontrada
[actualizar]
fuente