4.1 Early-Bound vs Late-Bound Entities

Compara los dos enfoques de desarrollo y cuándo usar cada uno

Cuando desarrollas plugins en Dataverse, tienes dos formas de trabajar con los datos: Late-Bound y Early-Bound. Esta decisión afecta cómo escribes tu código, qué errores puedes detectar en tiempo de compilación, y cuánto soporte tienes del IDE. Entender ambos enfoques te permite elegir el adecuado para cada situación.

Objetivos de aprendizaje

  • Entender la diferencia fundamental entre Late-Bound y Early-Bound
  • Conocer las ventajas y desventajas de cada enfoque
  • Saber cuándo usar cada uno según el escenario
  • Convertir entre ambos tipos en tu código

Late-Bound: el enfoque flexible

El desarrollo Late-Bound usa la clase Entity genérica para todo. Los campos se acceden mediante strings que representan el nombre lógico del atributo.


// Crear una cuenta usando Late-Bound
Entity cuenta = new Entity("account");
cuenta["name"] = "Contoso Ltd";
cuenta["telephone1"] = "555-1234";
cuenta["creditlimit"] = new Money(50000);

Guid cuentaId = service.Create(cuenta);

// Leer datos
Entity cuentaLeida = service.Retrieve("account", cuentaId, 
    new ColumnSet("name", "telephone1"));
    
string nombre = cuentaLeida.GetAttributeValue("name");

Es el enfoque que hemos usado en todas las lecciones anteriores. Es directo y no requiere configuración previa.

El problema de los strings mágicos

El código Late-Bound tiene un problema significativo: los errores de typo no se detectan hasta runtime. Si escribes "telepohne1" en lugar de "telephone1", el código compila perfectamente. Solo descubres el error cuando el plugin se ejecuta y el campo no existe.


// Esto compila, pero falla en runtime
entity["telepohne1"] = "555-1234";  // Typo: "telepohne" en lugar de "telephone"

// Visual Studio no te avisa del error
// Lo descubres cuando el plugin falla en producción

En proyectos grandes con decenas de plugins, estos errores se acumulan y son difíciles de diagnosticar.


Early-Bound: el enfoque tipado

El desarrollo Early-Bound usa clases generadas específicamente para cada entidad de tu modelo de datos. En lugar de Entity genérico, trabajas con clases como Account, Contact, Opportunity.


// Crear una cuenta usando Early-Bound
Account cuenta = new Account();
cuenta.Name = "Contoso Ltd";
cuenta.Telephone1 = "555-1234";
cuenta.CreditLimit = new Money(50000);

Guid cuentaId = service.Create(cuenta);

// Leer datos
Account cuentaLeida = service.Retrieve("account", cuentaId, 
    new ColumnSet("name", "telephone1")).ToEntity();
    
string nombre = cuentaLeida.Name;

Observa las diferencias: en lugar de strings, usamos propiedades tipadas. Name, Telephone1, CreditLimit son propiedades de la clase Account.

Errores en tiempo de compilación

Si intentas escribir cuenta.Telepohne1, Visual Studio te marcará un error inmediatamente porque esa propiedad no existe en la clase Account. No tienes que esperar a que el plugin se ejecute para descubrir el typo.

Además, el IDE te proporciona IntelliSense: cuando escribes "cuenta." te aparece la lista de propiedades disponibles. Puedes ver el tipo de cada campo sin consultar documentación.

Las clases vienen de algún sitio

Las clases Early-Bound no aparecen mágicamente. Son generadas a partir del esquema de tu organización de Dataverse usando herramientas como Power Platform CLI o XrmToolBox.

Esto significa que cuando el esquema cambia (añades un campo, creas una entidad), necesitas regenerar las clases para que reflejen los cambios. Es un paso adicional en tu flujo de trabajo.


Comparación directa

No hay un enfoque universalmente mejor. Cada uno tiene sus fortalezas:

IntelliSense y autocompletado: Early-Bound gana claramente. Con Late-Bound escribes strings a ciegas.

Detección de errores: Early-Bound detecta typos en compilación. Late-Bound los oculta hasta runtime.

Flexibilidad ante cambios de esquema: Late-Bound no necesita regenerar nada. Early-Bound requiere regenerar clases cuando el esquema cambia.

Tamaño del assembly: Late-Bound genera DLLs más pequeños. Early-Bound incluye todas las clases generadas.

Código con entidades dinámicas: Si tu plugin debe trabajar con cualquier entidad (sin saber cuál de antemano), Late-Bound es la única opción.


Cuándo usar cada enfoque

Después de trabajar en muchos proyectos, estas son mis recomendaciones:

Usa Early-Bound cuando:

  • El proyecto tiene múltiples desarrolladores o larga duración
  • El esquema de datos es relativamente estable
  • Quieres aprovechar IntelliSense y refactoring automático
  • La mantenibilidad del código es prioritaria

Usa Late-Bound cuando:

  • Es un prototipo o plugin simple de corta vida
  • El plugin debe trabajar con entidades determinadas en runtime
  • El esquema cambia frecuentemente durante desarrollo
  • Quieres evitar la dependencia de clases generadas

Híbrido: Muchos proyectos usan un enfoque híbrido. El Target que recibes en el plugin es siempre Entity (Late-Bound), pero puedes convertirlo a Early-Bound para el procesamiento.


Convirtiendo entre Late-Bound y Early-Bound

En la práctica, a menudo necesitas convertir. El contexto del plugin te da Entity genérico, pero tú quieres trabajar con clases tipadas.


public void Execute(IServiceProvider serviceProvider)
{
    var context = (IPluginExecutionContext)
        serviceProvider.GetService(typeof(IPluginExecutionContext));
    
    // El Target siempre viene como Entity (Late-Bound)
    Entity target = (Entity)context.InputParameters["Target"];
    
    // Convertir a Early-Bound
    Account cuenta = target.ToEntity();
    
    // Ahora puedes usar propiedades tipadas
    string nombre = cuenta.Name;
    Money creditLimit = cuenta.CreditLimit;
    
    // También funciona para Pre-Images
    if (context.PreEntityImages.Contains("preImage"))
    {
        Entity preImageEntity = context.PreEntityImages["preImage"];
        Account preImage = preImageEntity.ToEntity();
        string nombreAnterior = preImage.Name;
    }
}

El método ToEntity<T>() convierte un Entity genérico al tipo específico. Los campos que existen en ambos se mapean automáticamente.

Conversión en la otra dirección

A veces tienes un objeto Early-Bound y necesitas pasarlo a un método que espera Entity:


Account cuenta = new Account();
cuenta.Name = "Contoso Ltd";

// Convertir a Entity genérico
Entity entityGenerico = cuenta;  // Conversión implícita (Account hereda de Entity)

// También funciona
Entity entityExplicito = cuenta.ToEntity();

Generando las clases Early-Bound

Para usar Early-Bound, primero necesitas generar las clases. La forma más moderna es con Power Platform CLI:


# Autenticarse con la organización
pac auth create --url https://tuorg.crm.dynamics.com

# Generar clases para entidades específicas
pac modelbuilder build --outdirectory ./EarlyBound --entitynamesfilter "account;contact;opportunity"

# O generar todas las entidades (archivo grande)
pac modelbuilder build --outdirectory ./EarlyBound

Esto genera archivos .cs que añades a tu proyecto. Luego puedes usar las clases Account, Contact, etc. en tu código.

La alternativa es XrmToolBox con el plugin "Early Bound Generator", que ofrece una interfaz gráfica para seleccionar qué entidades generar.


Puntos clave

  • Late-Bound usa Entity genérico con strings para campos, flexible pero propenso a errores de typo
  • Early-Bound usa clases tipadas con propiedades, IntelliSense y errores en compilación
  • Las clases Early-Bound se generan con pac modelbuilder o XrmToolBox
  • Usa ToEntity<T>() para convertir de Late-Bound a Early-Bound
  • Para proyectos profesionales con equipos, Early-Bound es generalmente la mejor opción
  • Late-Bound sigue siendo útil para plugins genéricos que trabajan con cualquier entidad

Para profundizar

Inicia sesión e inscríbete para guardar tu progreso.
En este curso
¿Te ha resultado útil?