Guías de estilo C#

Las convenciones que esperan el SDK Dinaup y MyDinaup: proyecto, valores vacíos, fechas UTC, extensiones y cómo nombrar campos, secciones e informes.

Las convenciones de C# que esperan el SDK Dinaup, sus extensiones y MyDinaup. Con ellas tu código encaja con el SDK y con DinaZen.

Configuración del proyecto

<PropertyGroup>
  <TargetFramework>net10.0</TargetFramework>
  <Nullable>disable</Nullable>
  <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
  <Using Include="Dinaup.extensions" Static="true" />
  <Using Include="DemoUp.MyDinaup" />
  <!-- Alias con sufijo DTO para una fila de informe que se usa en muchos sitios -->
  <Using Include="DemoUp.MyDinaup.Reports.FuncionalidadD.RTGProyectosProyectosC.RTGProyectosProyectos_RowC">
    <Alias>ProyectoDTO</Alias>
  </Using>
</ItemGroup>

El Using estático de Dinaup.extensions deja .STR(), .IsEmpty() o .GetM() en todos los ficheros. SectionsD y Reports son clases parciales: en cada fichero, using static DemoUp.MyDinaup.SectionsD; y el de la categoría de informes que uses.

Valores vacíos en vez de nulables

Evita DateTime?, decimal? o Guid? salvo casos contados. Cada tipo tiene su valor vacío, el que reconocen .IsEmpty() y .STR():

TipoVacío
DateTimeDateTime.MinValue
decimal y numéricos0 ("Máximo 0" significa sin máximo)
GuidGuid.Empty (.STR() lo convierte en "")
string""

Fechas en UTC

Los campos de fecha de MyDinaup llevan el sufijo _UTC (FechaAlta_UTC) y los informes convierten con .ToDateTime_UTC(). El modelo no lleva horas locales: la zona del usuario se aplica al mostrar los datos, con CultureService.

Extensiones del SDK

Usa las extensiones en vez de comparar a mano:

if (_items.IsNotEmpty()) ProcessItems();   // no: _items?.Count > 0
if (f.NextRowId.IsEmpty()) return;         // no: f.NextRowId == Guid.Empty
if (codigo.LikeM(200, 201, 204)) return;
var valor = dic.GetM("key", "default");    // no lanza si la clave no está

.IsEmpty() e .IsNotEmpty() son un par: lista.IsEmpty(), no lista.IsNotEmpty() == false. Para convertir, .STR(), .INT(), .DEC() y .BOOL() escriben y leen en el formato de Dinaup, sin depender de la cultura del hilo.

MyDinaup

  • Campos por su constante, nunca por la clave pr_ en un literal. Si el campo cambia de nombre en Flex y regeneras, el compilador señala cada uso.

    wop.DataMainRow.Add(OportunidadesCRMD.OportunidadesCRMES.ReferenciaFase, faseId.STR());   // no: "pr_20040512046"
  • Secciones por su identificador tipado: {Seccion}D._SectionIDGUID, nunca un GUID copiado a mano. Para leer un registro, {Seccion}D.GetRowByIdAsync; para escribir una fila tipada, ToWriteOperation().

  • Estados por su catálogo: compara con Constants, no con el GUID ni con el texto.

    if (salida.EstadoID == Constants.EstadosDeSalidas.Pendiente.Id) Process();
  • Sufijo ReportData en la variable que guarda un informe, para distinguirla de sus filas (Rows, RowsDic).

    var motivosHorasExtrasReportData = new APIMotivosDeHorasExtrasC();
    await motivosHorasExtrasReportData.ExecuteQueryAsync(client, 1, 90000, "", true);   // el quinto argumento es adminMode
    dto.MotivosHorasExtra = motivosHorasExtrasReportData.RowsDic;
  • Referencia vacía en un filtro: Guid.Empty.STR(), que resuelve a "". Los booleanos van con "1" y "0". Ver QuickQuery.

  • Informes tolerantes desde el arranque: Dinaup.DinaupReportSettings.TolerateMissingColumns = true; en Program.cs, antes de crear ningún informe. Un modelo que va por delante del servidor carga las columnas que existen y avisa en el log de las que faltan. Ver Columnas ausentes.

En esta página