Miklix

Dynamics AX 2012 SysOperation Framework Quick Overview

Published: March 24, 2015 at 3:43:32 PM UTC

This article provides a quick overview (or cheat sheet) on how to implement processing classes and batch jobs in the SysOperation framework in Dynamics AX 2012 and Dynamics 365 for Operations.


The information in this post is based on Dynamics AX 2012 R3. It may or may not be valid for other versions. (Update: I can confirm that the information in this article is also valid for Dynamics 365 for Operations)


This post is just meant as a quick overview and cheat sheet. If you are new to the SysOperation framework, I strongly suggest that you read Microsoft’s white paper on the subject as well. The information here may be useful if you just need a quick brush up on the different classes involved in developing operations with this framework.

There are variations, but when I use the framework I typically implement three classes:

  • Data contract (should extend SysOperationDataContractBase)
  • Service (should extend SysOperationServiceBase)
  • Controller (must extend SysOperationServiceController)

Additionally, I may also implement a UIBuilder class (must extend SysOperationUIBuilder), but that is only necessary if the dialog for some reason has to be more advanced than what the framework generates automatically.


Data contract

The data contract holds the data members needed for your operation. It can be compared to the typical CurrentList macro defined in the RunBase framework, but implemented as a class instead. The data contract should extend SysOperationDataContractBase, but will work even if it doesn't. The advantage of extending the super class is that it provides some session information that may be handy.

[DataContractAttribute]
class MyDataContract extends SysOperationDataContractBase
{
    ItemId itemId;
}

In this example, the itemId is a data member. You need to implement a parm method for each data member and tag it with the DataMemberAttribute so the framework knows what it is. This enables the framework to automatically build the dialog for you.

[DataMemberAttribute]
public ItemId parmItemId(ItemId _itemId = itemId)
{
    ;

    itemId = _itemId;
    return itemId;
}


Service

The service class is the class that contains the actual business logic. It is not concerned with showing dialogs, batch processing or anything of the sort – that is the responsibility of the controller class. By separating this, you are more likely to design your code well and make more reusable code.

Like the data contract class, the service class does not need to inherit from anything in particular, but it should inherit from the SysOperationServiceBase class, at least if you expect that the service will be run as a batch job, as the super class provides some information about the batch context. The method that starts the operation (i.e. runs the business logic) must take an object of your data contract class as input and should be decorated with the [SysEntryPointAttribute]. For example:

class MyService extends SysOperationServiceBase
{
}

with a method called run:

[SysEntryPointAttribute]
public void run(MyDataContract _dataContract)
{
    // run business logic here
}


Controller

The controller class handles the execution and batch processing of your operation. It also makes sure that the code is executed in CIL for maximum performance. The controller class typically inherits from the SysOperationServiceController class, although there are other options as well.

class MyController extends SysOperationServiceController
{
}

The constructor of the super class takes a class name, method name and (optionally) execution mode as parameters. The class and method names should be the name of your service class and the method that should be run on it. So, you might implement your controller’s construct method like this:

public static MyController construct()
{
    ;

    return new MyController(classStr(MyService),
    methodStr(MyService, run));
}

Then the main method of the MyController class can be as simple as

public static void main(Args _args)
{
    ;

    MyController::construct().startOperation();
}

And you’re basically done. The above is obviously a very simple example and the framework contains a plethora of other options and possibilities, but this serves as a quick overview if you need a brush up when you haven’t used the framework for a while.

Share on BlueskyShare on FacebookShare on LinkedInShare on TumblrShare on XShare on LinkedInPin on Pinterest

Mikkel Bang Christensen

About the Author

Mikkel Bang Christensen
Mikkel is the creator and owner of miklix.com. He has over 20 years experience as a professional computer programmer/software developer and is currently employed full-time for a large European IT corporation. When not blogging, he spends his spare time on a vast array of interests, hobbies, and activities, which may to some extent be reflected in the variety of topics covered on this website.