# How to Add Custom Business Logic to a SyteLine IDO with an Extension Class

> Source: https://netray.co/erp-help/syteline-ido-extension-class-custom-business-logic
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: ERP Help

## Short answer

SyteLine lets you add validation, defaulting, and side-effect logic to any IDO without touching Infor's generated code, by writing an IDO extension class in C# and hooking into the object's Before/After events. The extension assembly is compiled, deployed next to the IDO Runtime, and picked up once the runtime cache is refreshed.

## Kind

advanced

## System

syteline

## Erp

Infor SyteLine (CloudSuite Industrial)

## Module

Customization / IDO Extension Classes

## Query

how to add custom business logic to a SyteLine IDO with an extension class

## Alternate Queries

- SyteLine IDO extension class BeforeAdd AfterModify example
- where do IDO extension DLLs get deployed in SyteLine
- how to override IDO save logic in CSI without modifying core code
- SyteLine custom validation on save IDO

## Applies To

SyteLine 8.x, 9.x and Infor CloudSuite Industrial (CSI) on-prem and multi-tenant; the IDO architecture is consistent across these releases.

## Steps

### Build and deploy an IDO extension class

**Items:**

In Application Studio, open the IDO Collection you want to extend (for example CustOrdr) and confirm the Extendable property is enabled so the generated class exposes extension hooks.

Create a Visual Studio class library project and reference the Mongoose.IDO and Mongoose.Data assemblies from the SyteLine installation's bin folder, matching your SyteLine version exactly.

Add a class that follows the IDO's extension naming convention (for example CustOrdrExtension) and implement the Before/After event methods you need: BeforeAdd, AfterAdd, BeforeModify, AfterModify, BeforeDelete, AfterDelete.

Write validation or defaulting logic inside those methods, throwing a business rule exception, not a raw .NET exception, when a save should be rejected so the error surfaces cleanly in the SyteLine UI.

Build the project in Release mode and confirm there is no version mismatch between the referenced Mongoose assemblies and the target server's installed version.

Copy the compiled extension DLL to the IDO Runtime's bin directory on the application server, the same folder that holds the generated IDO assemblies.

Recycle the IDO Runtime application pool in IIS, or restart the IDO Runtime Windows service, then clear the IDO cache so the runtime loads the new extension instead of the cached generated-only class.

Test through a thin client or Application Studio's test harness before rolling the DLL to other environments, and keep the source extension project under source control per IDO.

## Sections

### Why use an extension class instead of modifying the IDO

**Body:**

Application Studio lets you edit generated IDO code directly, but any change made that way is overwritten the next time the IDO is regenerated from the data dictionary, which happens routinely during upgrades and patching. An extension class lives in a separate assembly that is never touched by regeneration, so the customization survives version upgrades, CTP updates, and cloud maintenance windows without manual reapplication.

The tradeoff is that extension classes can only hook the events the IDO exposes, Before/After Add, Modify, Delete and a handful of others, not arbitrary points inside generated logic. For anything deeper you are into modifying generated code directly, which support and upgrade teams generally advise against for supported CloudSuite tenants.

### Common patterns: validation, defaulting, and cross-IDO calls

**Body:**

The most common use of a BeforeAdd or BeforeModify override is field validation that cannot be expressed as a simple Application Studio business rule, for example a check that spans multiple related records. AfterModify is the usual place to trigger a downstream update on a related IDO, such as recalculating a total on a parent record after a line changes.

Because AfterAdd and AfterModify run synchronously inside the save transaction, anything slow placed there, an external web service call, an email send, makes every user's save feel slow. Keep synchronous extension logic fast, and push anything that talks to an external system to an asynchronous flow, such as an ION BOD or a scheduled job, instead.

**Code:**

public class CustOrdrExtension : CustOrdrExtensionBase
{
    public override void BeforeAdd(IDORuntimeContext ctx, IDORow row)
    {
        if (row.GetString("ShipTo") == null)
            throw new IDOBusinessRuleException("Ship-to is required.");
    }
}

### Debugging extension classes that don't fire

**Body:**

The number one cause of an extension that appears to do nothing is a stale IDO Runtime cache: the DLL was copied to the bin folder but the application pool or Windows service was never recycled, so the runtime is still using the previously loaded assembly. Recycle the pool or restart the service, then retest before assuming the code itself is wrong.

The second most common cause is a version mismatch between the Mongoose assemblies referenced at build time and the ones actually installed on the target server, which can cause the extension to fail to load silently instead of throwing an obvious error. Confirm both versions match, and check the IDO Runtime's startup log for load failures.

### Extension classes vs Mongoose scripts vs Business Rules

**Body:**

Mongoose scripts run on the form and are for UI-layer logic, client side, per form. Application Studio's declarative business rules handle simple field-level validation and defaulting without code. Extension classes are for anything requiring real code logic that must hold true regardless of which client, thin client, mobile, or an integration, calls the IDO, because they run at the IDO layer, not the form layer.

Default to a business rule first if the requirement is a simple field-level check, and reach for an extension class only when the logic needs to be enforced consistently no matter how the record is saved.

## Pitfalls

- Editing generated IDO code directly instead of using an extension class, so the change disappears on the next regeneration.
- Referencing the wrong version of Mongoose.IDO.dll during build, producing a DLL that fails to load or throws obscure binding errors at runtime.
- Forgetting to recycle the IDO Runtime app pool or service after deployment, then assuming the extension is broken when it is simply still running the cached version.
- Putting slow external calls, web service calls, email sends, inside AfterAdd or AfterModify, which blocks the user's save transaction under load.
- Throwing a raw .NET exception instead of an IDO business-rule exception, so the end user sees an ugly unhandled error instead of a clean validation message.
- Not testing the extension against multi-site or intercompany scenarios, where the same IDO method can be called with a different site context than expected.

## Ai Angle

When an IDO extension throws an unexpected error under load, ERPray can be pointed at the SyteLine source tree and deployment folder together, correlate the failing IDO method with the exact extension class and Mongoose assembly version deployed on that server, and flag a version mismatch or a slow AfterModify call before an afternoon is spent reproducing it in Application Studio. For teams building new extensions, SyteRay can draft the extension class skeleton, including the Before/After method stubs for the target IDO, from a plain-English description of the validation rule.

## Faq

### Can I add a completely new field to an IDO with an extension class?

**Answer:** No. New fields have to be added to the underlying table and exposed through the IDO's properties in Application Studio first. An extension class only adds behavior around existing properties and methods, it cannot introduce new persisted columns on its own.

### Do extension classes work the same way in CloudSuite Industrial multi-tenant?

**Answer:** The extension mechanism is the same, but in multi-tenant CSI you typically deploy through Infor's change management process rather than copying a DLL to a server yourself, since you do not have direct file system access. Work with your CSI partner or Infor support on the approved deployment path.

### Why does my BeforeAdd logic run twice on one save?

**Answer:** This usually means the same IDO method is being invoked once by the parent transaction and again by a related IDO or Mongoose script calling back into it, or a grid is issuing both a validate and a save call. Add a timestamped log line inside the method to see who is actually calling it.

### Can extension classes call out to a REST API?

**Answer:** Yes, but do it in a way that cannot hang the save transaction, ideally with a short timeout and a fallback that does not block the record from saving if the external call fails, or move the integration to an asynchronous ION or BOD flow instead.

### Is there a supported way to see which extension classes are currently loaded?

**Answer:** Check the IDO Runtime's startup log for the assemblies it loaded from the bin folder, or use Application Studio's IDO test tool to invoke the method and watch for the custom behavior. There is no single admin screen listing active extensions, so keeping your own inventory per IDO is worth doing.

## Search terms

syteline ido extension class, syteline custom business logic, syteline beforeadd aftermodify, csi ido extension deploy, syteline application studio extendable ido, mongoose ido dll, syteline ido runtime cache, infor syteline customization without modifying core code, syteline business rules vs extension class, syteline ido developer guide

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
