The SysOperation Framework in Dynamics 365 Finance & Operations
Question 8 — The modern batch framework, its components, and why it replaced RunBaseBatch.
Interview Question
Model Answer (Short)
SysOperation is the recommended framework for building batch and long-running operations in
D365 F&O. It follows an MVC-style pattern that separates data from logic: a
data contract holds the parameters, a service class contains the business logic,
a controller orchestrates execution, and an optional UI Builder customises the
dialog. It replaces RunBaseBatch, where parameters, packing/unpacking, dialog and logic were all mixed
into a single class. SysOperation also supports running synchronously, asynchronously, on a batch server,
or as a scheduled batch, and it uses attributes and SysOperationSandbox-friendly patterns
instead of manual pack()/unpack().
The Four Core Components
1. Data Contract
A simple class decorated with [DataContractAttribute] that defines the parameters. Each parameter is
exposed through a parm method marked with [DataMemberAttribute]. The framework
serialises this contract automatically — no manual pack/unpack required.
2. Service
A class (typically extending SysOperationServiceBase) that contains the actual
business logic. Its operation method receives the data contract as a parameter and performs the work.
3. Controller
A class extending SysOperationServiceController that orchestrates the process — it
registers the service and method, manages the execution mode, and shows the parameter dialog. It is the entry point
(usually launched from a menu item).
4. UI Builder (optional)
A class extending SysOperationAutomaticUIBuilder used only when you need to
customise the dialog — for example adding lookups, conditional visibility, or grouping of fields
beyond the automatically generated dialog.
Execution Modes
| Mode | Enum value | Behaviour |
|---|---|---|
| Synchronous | SysOperationExecutionMode::Synchronous |
Runs on the client thread; user waits for completion. |
| Asynchronous | SysOperationExecutionMode::Asynchronous |
Runs without blocking the client (via async server call). |
| Reliable Asynchronous | SysOperationExecutionMode::ReliableAsynchronous |
Queued to the batch server for a single reliable run. |
| Scheduled Batch | SysOperationExecutionMode::ScheduledBatch |
Creates a recurring/scheduled batch job. |
Prerequisites (Rule 5)
- Visual Studio with the Dynamics 365 developer tools.
- A custom model / package for your objects.
- An action menu item pointing to the controller to launch the operation.
- A configured batch group / batch server if running in batch.
Code Example — Data Contract
[DataContractAttribute]
class AbcPostInvoiceContract
{
CustAccount custAccount;
FromDate fromDate;
[DataMemberAttribute('CustAccount')]
public CustAccount parmCustAccount(CustAccount _custAccount = custAccount)
{
custAccount = _custAccount;
return custAccount;
}
[DataMemberAttribute('FromDate')]
public FromDate parmFromDate(FromDate _fromDate = fromDate)
{
fromDate = _fromDate;
return fromDate;
}
}
Service class (business logic)
class AbcPostInvoiceService extends SysOperationServiceBase
{
public void processInvoices(AbcPostInvoiceContract _contract)
{
CustAccount custAccount = _contract.parmCustAccount();
FromDate fromDate = _contract.parmFromDate();
// ... business logic here ...
info(strFmt("Processing invoices for %1 from %2",
custAccount, date2Str(fromDate, 321, 2, 3, 2, 3, 4)));
}
}
Controller (entry point)
class AbcPostInvoiceController extends SysOperationServiceController
{
public void new()
{
super();
// Register the service class and the method to run
this.parmClassName(classStr(AbcPostInvoiceService));
this.parmMethodName(methodStr(AbcPostInvoiceService, processInvoices));
// Default execution mode (can be changed by the user in the dialog)
this.parmExecutionMode(SysOperationExecutionMode::Synchronous);
}
public ClassDescription caption()
{
return "Post customer invoices";
}
// Menu item calls this static construct method
public static AbcPostInvoiceController construct()
{
return new AbcPostInvoiceController();
}
public static void main(Args _args)
{
AbcPostInvoiceController controller = AbcPostInvoiceController::construct();
controller.startOperation();
}
}
SysOperation vs. RunBaseBatch
| Aspect | SysOperation | RunBaseBatch |
|---|---|---|
| Design pattern | MVC — separation of concerns | Monolithic single class |
| Parameter persistence | Automatic (data contract serialisation) | Manual pack() / unpack() |
| Dialog | Auto-generated from contract; optional UI Builder | Coded manually in dialog() |
| Execution modes | Sync, Async, Reliable Async, Scheduled Batch | Interactive or batch only |
| Recommended status | Current / preferred | Legacy (avoid for new code) |
Points the interviewer wants to hear
- Four components: data contract, service, controller, and optional UI builder.
- Parameters persist automatically — no manual pack/unpack like RunBaseBatch.
- Uses attributes:
[DataContractAttribute]and[DataMemberAttribute]. - Supports Sync, Async, Reliable Async and Scheduled Batch execution.
- It is the preferred framework; extend it rather than
RunBaseBatchfor new work.
Likely Follow-up Questions
- When do you actually need a UI Builder class?
- How does SysOperation persist parameters between runs without pack/unpack?
- What is the difference between Asynchronous and Reliable Asynchronous mode?
- How do you add a query to a SysOperation dialog?
Key Takeaway
SysOperation brings a clean MVC separation to batch development — contract for data, service for logic, controller for orchestration, and an optional UI builder for the dialog. It removes RunBaseBatch's manual plumbing and supports multiple execution modes, making it the standard choice for new operations.