Late-bound and early-bound programming using the SDK for .NET
When you work with the SDK for .NET assemblies, you have two programming 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 tables (entities) or columns (attributes) that weren't available when your code was compiled.
Late-bound
Late-bound programming uses the Entity class where you need to refer to table rows and columns (entities and attributes) using their LogicalName
property values:
Relationships don't 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 large.
The main disadvantages are:
- You don't get compile time validation on 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 specifying the 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 table and column definitions (entity and attribute metadata) for a specific environment using the code generation tool Power Platform CLI pac modelbuilder build command. More information: Generate classes for early-bound programming using the SDK for .NET
After generating early-bound classes using the code generation tool, you'll enjoy a better experience while you write code because classes and properties use the respective SchemaName
property values:
Simply instantiate the class and let Visual Studio IntelliSense 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 provides you with a pair of request and response classes to use with these custom actions. More information: Custom Actions
Classes are generated using table definitions from a specific environment instance and each instance may have different tables and columns where these can change over time. You may need to write code to work for tables that aren't 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 programming 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 code to write; code is more readable | More code to write; code is less readable |
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 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 context object.
context.AddToAccountSet(testaccount);
context.SaveChanges();
If a custom attribute wasn't 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 SDK for .NET
Create table rows using the SDK for .NET
Retrieve a table row using the SDK for .NET
Query data using the SDK for .NET
Update and delete table rows using the SDK for .NET
Associate and disassociate table rows using the SDK for .NET
IOrganizationService Interface
Using OrganizationServiceContext