Late-bound and Early-bound programming using the Organization service

When you work with the Organization service assemblies you have two styles you can use: late-bound and early-bound.

The key difference between early and late binding involves type conversion. While early binding provides compile-time checking of all types so that no implicit casts occur, late binding checks types only when the object is created or an action is performed on the type. The Entity class requires types to be explicitly specified to prevent implicit casts.

Late binding allows you to work with custom entities or attributes that weren't available when your code was compiled.

Late-Bound

Late-bound programming uses the Entity class and you need to refer to entities, and attributes using their LogicalName property values:

Relationships do not have a LogicalName property, so the RelationshipMetadataBase.SchemaName property is used.

The main advantage for late-bound programming is that you don't need to generate the classes or include that generated file within your projects. The generated file can be quite large.

The main disadvantages are:

  • You don't get compile time validation of names of entities, attributes, and relationships.
  • You need to know the names of the attributes and relationships in the metadata.

Tip

A tool that you can use to find this information easily is the Metadata Browser. This is an app you can download and install in your organization. More information: Browse the metadata for your environment

Example

The following example creates an account using the late-bound style.

//Use Entity class with entity logical name
var account = new Entity("account");

// set attribute values
    // string primary name
    account["name"] = "Contoso";            
    // Boolean (Two option)
    account["creditonhold"] = false;
    // DateTime
    account["lastonholdtime"] = new DateTime(2017, 1, 1);
    // Double
    account["address1_latitude"] = 47.642311;
    account["address1_longitude"] = -122.136841;
    // Int
    account["numberofemployees"] = 500;
    // Money
    account["revenue"] = new Money(new decimal(5000000.00));
    // Picklist (Option set)
    account["accountcategorycode"] = new OptionSetValue(1); //Preferred customer
                
//Create the account
Guid accountid = svc.Create(account);

Early-Bound

Early-bound programming requires that you first generate a set of classes based on the metadata for a specific organization using the code generation tool (CrmSvcUtil.exe). More information: Generate classes for early-bound programming using the Organization service

When you have generated early-bound entity classes using the code generation tool you will enjoy a better experience while you write code because classes and attribute properties using the respective SchemaName property values:

Simply instantiate the class and let IntelliSense in Visual Studio provide the names of properties and relationships.

The classes generated for early-bound programming can also include definitions for any custom actions that are defined for the environment. This will provide you with a pair of request and response classes to use with these custom actions. More information: Custom Actions

There is also an option to extend the code generation tool to change the output. One extension creates enums for each optionset option value. This provides a better experience because you don't have to look up the integer value for each option. More information: Create extensions for the code generation tool

However, because the classes are generated using metadata from a specific instance, and each instance may have different entities and attributes, and these can change over time. You may need to write code to work for entities that are not present when you generate the strongly typed classes.

Important

If you are using the OrganizationServiceProxy to provide the IOrganizationService methods you will use, you must call the OrganizationServiceProxy.EnableProxyTypes() method to enable early bound types.

Example

The following example creates an account using the early-bound style.

var account = new Account();
// set attribute values
    // string primary name
    account.Name = "Contoso";
    // Boolean (Two option)
    account.CreditOnHold = false;
    // DateTime
    account.LastOnHoldTime = new DateTime(2017, 1, 1);
    // Double
    account.Address1_Latitude = 47.642311;
    account.Address1_Longitude = -122.136841;
    // Int
    account.NumberOfEmployees = 500;
    // Money
    account.Revenue = new Money(new decimal(5000000.00));
    // Picklist (Option set)
    account.AccountCategoryCode = new OptionSetValue(1); //Preferred customer

//Create the account
Guid accountid = svc.Create(account);

Choose which style

Which style you choose to use is up to you. The following table provides the advantages and disadvantages for each.

Early-bound Late-bound
You can verify entity, attribute, and relationship names at compile time No compile time verification of entity, attribute, and relationship names
You must generate entity classes You don't need to generate entity classes
Better IntelliSense support Less IntelliSense support
Less, more readable code More, less readable code
Very slightly less performant Very slightly more performant

Mix early and late bound

Because all the generated classes inherit from the Entity class used with late-bound programming, you can work with entities, attributes, and relationships not defined within classes.

Examples

The following example shows one way to mix early and late binding methods using OrganizationServiceContext.

// Create an organization service context object  
AWCServiceContext context = new AWCServiceContext(_serviceProxy);  
  
// Instantiate an account object using the Entity class.  
Entity testaccount = new Entity("account");  
  
// Set several attributes. For account, only the name is required.   
testaccount["name"] = "Fourth Coffee";  
testaccount["emailaddress1"] = "marshd@contoso.com";  
  
// Save the entity using the organization service context object.  
context.AddToAccountSet(testaccount);  
context.SaveChanges();  
  

If a custom attribute was not included in the generated classes, you can still use it.

var account = new Account();
// set attribute values
    // string primary name
    account.Name = "Contoso";
    // A custom boolean attribute not included in the generated classes.
    account["sample_customboolean"] = false;


//Create the account
Guid accountid = svc.Create(account);

Assign an early bound instance to a late bound instance

The following sample shows how to assign an early bound instance to a late bound instance.

Entity incident = ((Entity)context.InputParameters[ParameterName.Target]).ToEntity<Incident>();  
Task relatedEntity = new Task() { Id = this.TaskId };  
  
incident.RelatedEntities[new Relationship("Incident_Tasks")] =   
new EntityCollection(new Entity[] { relatedEntity.ToEntity<Entity>() });  

See also

Entity Operations using the Organization service
Create entities using the Organization Service
Retrieve an entity using the Organization Service
Query data using the Organization service
Update and Delete entities using the Organization Service
Associate and disassociate entities using the Organization Service
IOrganizationService Interface
Using OrganizationServiceContext