Suprimir los warnings de FxCop para un proxy WCF

Qué «antiestético» es el código con warnings, ¿verdad? Una de las cosas que más me llamó la atención, y tengo que reconocer que para mal, es la cantidad que saltan al pasar el FxCop sobre los proxies que genera Windows Communication Foundation. Da una sensación horrible, y cuando uno suprime los warnings, ver que al regenerar los proxies volvemos a la situación anterior, es tremendamente frustrante. Alguno estará pensando… ¿y qué hace este cenutrio pasando el analizador estático a código generado de forma automática? Bueno… mi problema es que no puedo elegir… al activar el análisis de código en las propiedades de un proyecto, se activa sobre todos los fuentes… incluidos los proxies. No puedo vivir sin FxCop, y tampoco puedo vivir con los warnings… supongo que hay amores que matan.


Hoy he estado buscando una forma de suprimir los warnings sobre los proxies sin que al regenerarlos se borren las supresiones, y he aquí que he dado con una receta para el éxito.


El truco consiste en poner las supresiones en el «GlobalSupressions.cs». Los que uséis FxCop «a secas», podéis hacer esto de una forma bastente sencilla… sólo hay que seleccionar el error y tras hacer click con el botón derecho, seleccionar «Copy As -> SuppressMessage». Por desgracia, los que tenemos el FxCop integrado en Visual Studio 2005, no tenemos esta opción (nos la han prometido para Visual Studio Orcas).


No todo está perdido… todavía hay una solución. Solo, tenemos que actuar de la siguiente forma:



  • Suprimimos el error que ha detectado el analizador de código sobre el proxy. Esto meterá un atributo «SupressMessage» sobre el punto en el que se ha detectado el error. Nos fijamos en si el SupressMessage está sobre una clase, o sobre un método.

  • Quitamos el SupressMessage del proxy, y lo copiamos en el GlobalSupressions… poniéndole como prefijo «assembly». Es decir:

    [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(«Microsoft.Usage», «CA2239:ProvideDeserializationMethodsForOptionalFields»)]

  • Ahora tenemos que indicar dónde se encuentra el error original. Para eso, debemos especificar cual era el ámbito de la regla FxCop que ha saltado. Si ha saltado sobre una clase, el ámbito es «type», y si ha saltado sobre un método, es «method». Añadimos el ámbito por medio del parámetro «Scope» del atributo SuppressMessage:

    [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(«Microsoft.Usage», «CA2239:ProvideDeserializationMethodsForOptionalFields», Scope = «type»]

    o por ejemplo…

    [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(«Microsoft.Design», «CA1051:DoNotDeclareVisibleInstanceFields», Scope = «member»]

  • Por último, tenemos que indicar el punto en el que se encontraba el error. Para eso, utilizaremos el parámetro de nombre «Target», en combinación con el siguiente valor:


    • Si se trataba de una clase, se indica el nombre totalmente cualificado de la clase (con namespace)

    • Si se trataba de una propiedad o un miembro, el nombre totalmente cualificado del miembro.

    • Si se trataba de un método, el nombre totalmente cualificado del método, sin incluir los nombres de los argumentos (sólo los tipos) e indicando el tipo de retorno al final (con dos puntos, al estilo de C++).

    • Por ejemplo:

      [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(«Microsoft.Usage», «CA2239:ProvideDeserializationMethodsForOptionalFields», Scope = «type», Target = «Sisteplant.Captor.Terminal.EventsBrokerProxy.EventInfo»)]

      [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(«Microsoft.Design», «CA1051:DoNotDeclareVisibleInstanceFields», Scope = «member», Target = «Sisteplant.Captor.Terminal.WorkplaceServiceProxy.GetInManufacturingOrdersRequest.dateTime»)]

      [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(«Microsoft.Design», «CA1030:UseEventsWhereAppropriate», Scope = «member», Target = «Sisteplant.Captor.Terminal.EventsBrokerProxy.IEventsBroker.RaiseEvent(Sisteplant.Captor.Terminal.EventsBrokerProxy.EventInfo):System.Void»)]


Alguno podría tratar de suprimir varios errores tratando de establecer el Scope a «namespace»… pues bien, ni lo intentéis porque no funciona… hay que ir suprimiendo los errores uno por uno, y la lista de errores que os vais a encontrar es probablemente esta:


CA1030:UseEventsWhereAppropriate
CA1051:DoNotDeclareVisibleInstanceFields
CA1709:IdentifiersShouldBeCasedCorrectly
CA1711:IdentifiersShouldNotHaveIncorrectSuffix
CA2227:CollectionPropertiesShouldBeReadOnly
CA2239:ProvideDeserializationMethodsForOptionalFields



En fin, esperemos que la calidad del código generado automáticamente mejore… y no sólo haciendo que funcione el atributo «AutoGeneratedCode» que el svcutil añade a los proxies (y que por cierto, el FxCop no se toma muy en serio). Yo me pregunto… ¿tanto cuesta generar código que supere la regla CA1709?



Nueva guía de optimización de Analysis Services 2005

Microsoft ha publicado una guía de optimización para SSAS 2005. En la guía menciona que es aplicable a partir del Service Pack 2 (que estará disponible en breve y del que hace tiempo que se puede descargar una CTP)… sin embargo, muchos de los puntos que indican son aplicables desde ahora. De momento sólo le he podido echar un vistazo rápido, pero prometo contaros mis impresiones tras una lectura detallada. Podéis descargaros la guía desde esta URL:


http://download.microsoft.com/download/8/5/e/85eea4fa-b3bb-4426-97d0-7f7151b2011c/SSAS2005PerfGuide.doc

Clase Singleton vs. estática

Esta es una duda que nos suele surgir muy a menudo a todos… ¿merece la pena desarrollar un Singleton, o me basta con una clase estática? ¿Cual es el enfoque correcto? ¿Es el Singleton la clase estática de los «pijos», o la clase estática el Singleton de los pobres? La verdad es que como siempre que hablamos de estos temas, suele haber opiniones para todos los gustos… así que contribuiré con una más a que el mundo sea todavía más caótico.


Bueno, como todos sabéis, una clase estática y una singleton tienen, a grandes rasgos, una gran diferencia: la clase Singleton es aquella para la que existe una única instancia accesible por nuestra aplicación y la clase estática es aquella para la que ni siquiera existe instancia (todos sus métodos y miembros son estáticos). Aparentemente sirven para lo mismo, así que… ¿por qué debería usar un Singleton?



  • El principal motivo, a mi entender, es la capacidad que tiene el Singleton de evolucionar hacia una clase que tenga más de una instancia. Puede que no vemos sentido a esto, pero el principio de encapsulación que hay detrás de un Singleton es el mismo que distingue una propiedad de un miembro, o un evento de un delegado. La clase que hace un GetInstance de un Singleton asume que está obteniendo «la instancia» de esa clase, ¡pero nada nos obliga a que esa clase tenga que ser única! Es decir… ¿cúanto nos costaría ampliar el código que os pongo abajo, para añadirle un contador de instancias y permitir un máximo de tres? (lo dejo como ejercicio espiritual para mentes ávidas de pensar). En resumen… un puntito para el Singleton.



    class Singleton
    {


       private static Singleton _instance;


       private Singleton()
       {
       }


       public static Singleton Instance
       {
       
    get
           
    {
              
    if (_instance == null)
               {
                   _instance =
    new Singleton();
               }
              
    return _instance;
            }
      
    }
    }



  • Otra ventaja del Singleton está en que los métodos no son estáticos, y por tanto se pueden sobreescribir en las clases herederas (son «overrideables»). No se puede hacer un override de un método estático. Vamos, que si pretendemos hacer una jerarquía de clases de instancia única, más nos vale que tiremos hacia el singleton… de lo contrario tendremos problemas. Singleton 2, Estática 0

  • La clase Singleton tiene instancia, y eso en sí ya es una ventaja. Por ejemplo, eso nos facilitará que nuestro Singleton pueda implementar interfaces que sencillamente una clase estática nunca podrá implementar. De nuevo, la clase Singleton puede «crecer» con más facilidad que la estática en este sentido. Singleton 3, Estática 0

  • En cuanto a qué es mejor para implementar una clase Thread Safe, fijaros que básicamente el problema que tenemos es el mismo: si tenemos varios threads modificando miembros de la clase, habrá que sincronizarlos y asegurarnos de que sólo uno es capaz de alterar un miembro cada vez. La clase Singleton tiene una peguilla adicional, y es que tenemos que proteger también el método que obtiene la instancia. No es un gran problema… hay un artículo muy interesante de cómo hacerlo AQUÍ. Yo diría que en cuanto a la seguridad de threads, ambas clases «empatan».

  • Algunos opinan que la clase Singleton es más adecuada para representar clases que mantienen un estado. En realidad esta puede ser más una cuestión de gusto (buen gusto, se entiende) que un requisito real. Ambas clases pueden contener perfectamente un estado. De nuevo otro empate.

  • ¿Y dónde gana la clase estática? En su simplicidad. Así que como el «Keep it Simple» es un argumento que vale por tres, ¡digamos que Singleton y clase estática empatan a puntos! Singleton 3, Estática 3

Vamos, que la idea con la que nos debemos quedar es que una clase Singleton va a hacer nuestro programa un pelín más difícil de comprender, así que como todo, es un recurso que sólo debemos utilizar si es necesario. Y yo, como siempre, que sigo sin mojarme… ¿quieres mojarte tú? ¡¡pues mándame tus comentarios!! Los espero ansioso.