SysOperation Framework in D365

Share this:

Do you have a process that you need to run in the background of Microsoft Dynamics 365 F&S? SysOperation Framework in D365 is made for doing this. In this article I will show you the quickest and simplest way of creating the needed classes.

When To Use SysOperation Framework in D365

First, what are some scenarios where you might want a process or job to run in the background?

  • The most common scenario is that you have a set of records that you need to process or do some calculation for. Perhaps you have used a Data Entity or Service to bring data into a staging table. Now you need to loop through each record and create functional data inside the system. SysOperation Framework in D365 is made for just this sort of thing.
  • Another scenario is that you have some process that you normally run on a single record in a form, but now you want to run the process on many records. SysOperation Framework in D365 can easily be setup to loop through a group of records and call existing code to process each record.
  • Lastly, is a scenario that is often under used. You may have a button on a form that when clicked will run some process on a record. If that process does not run instantly and you do not need to immediately use the result of the process, you can offload that work to job that uses SysOperation Framework in D365. Perhaps running a single process only takes 15 seconds to run, but by letting the system do the work in the background you can improve the user experience greatly. Typically a user would have to wait those 15 seconds while the operation completes. But now they are given back control immediately and can continue working.

Create The Contract

The contract class contains any data we need to directly send to the process. Create a new class in D365, with the attribute [DataContractAttribute] at the top. And by convention the name of the class should end with the word ‘Contract’. Add member variables and parm methods for each value that needs to be passed to the process doing the work. Perhaps you have a From Date and To Date that you are running the process for. In the simplest SysOperation Framework scenarios, this class can be left blank.

[DataContractAttribute]
class rsmTutSysOperationsContract
{
}

Create The Service

The service class contains the code that actually performs the processing. Create a new class in D365, that extends the class SysOperationServiceBase. Also, by convention, the name of the class should end with the word ‘Service’. Create a public method, named whatever you would like, that takes a single parameter which is of the type of the Contract class.

class rsmTutSysOperationsService extends SysOperationServiceBase
{
    public void process(rsmTutSysOperationsContract _contract)
    {
        //Do something
    }
}

Create The Controller

The controller class really just configures the SysOperation Framework process. Create a new class in D365, that extends the class SysOperationServiceController.

class rsmTutSysOperationsController extends SysOperationServiceController
{

}

Then add these four methods.

  1. Create a new method that calls super. It needs to pass a)The name of the Service class, the name of the method on the service Class, and the execution mode.
protected void new()
    {
        super(classStr(rsmTutSysOperationsService), methodStr(rsmTutSysOperationsService, process), SysOperationExecutionMode::Synchronous);
    }

2. Create a method named ‘defaultCaption’. This will override the base method and return the name of the job.

public ClassDescription defaultCaption()
    {
        return "Process Job";
    }

3. Create a method named ‘construct’. This will instantiate the controller class and set the execution mode.

public static rsmTutSysOperationsController construct(SysOperationExecutionMode _executionMode = SysOperationExecutionMode::Synchronous)
    {
        rsmTutSysOperationsController controller;
        controller = new rsmTutSysOperationsController();
        controller.parmExecutionMode(_executionMode);
        return controller;
    }

4. Lastly, create a method named ‘main’. The main method is always called by the menu item. This method will call ‘startOperation’ which actually calls the Service class’s method to do the work.

public static void main(Args _args)
    {
        rsmTutSysOperationsController controller;
        controller = rsmTutSysOperationsController::construct();
        controller.parmArgs(_args);
        controller.startOperation();
    }

Create The Action Menu Item

Create a new action menu item that will call the controller class. In my example, the controller class is named rsmTutSysOperationsController. So I will name my action menu item the same thing. In the Properties, set the ‘Object Type’ to be Class, and the ‘Object’ to be name of the controller class.

SysOperation Framework action menu item

Set the Label in the menu item properties.

Then add the menu item to an appropriate menu.

Parameters, Defaults, Validation, Mandatory and UIBuilder

Please see these other articles for more advanced SysOperation Framework functionality.

First, learn how to add parameters to your batch jobs. D365 SysOperation Framework Parameters

Next, override the drop-downs to show only validate options. D365 SysOperation Framework Override Lookups

After adding parameters to a SysOperation Framework batch job, you may want to set those parameters to start with an initial value. Learn how to set a D365 SysOperation Framework default value.

Additionally, add validation to the parameters. D365 SysOperation Framework Validation

Lastly, learn to add D365 SysOperation Framework mandatory parameters that show a red outline and a star to indicate the field must be populated.

For another great reference on how to create classes using the SysOperation Framework in D365, see this article.

Conclusion

The ability to let the system run processes in the background and allow the user to continue with their work in incredibly useful. It is also very easy to setup and use. These jobs can scheduled to run on a reoccurrence, or they can be run a single time. I hope that this article, and these jobs, will save you some time.

Peter Ramer
Peter Ramer is a part of the Managed Application Services team at RSM working on Microsoft Dynamics 365. He focuses on the Retail and Commerce industries. When he is not solving problems and finding ways to accelerate his clients' business, he enjoys time with his three kids and amazing wife.

Share this:

29 thoughts on “SysOperation Framework in D365

Add yours

  1. Very nice post. I just stumbled upon your blog and wanted
    tto say that I’ve truly enjoyed surfing around ylur
    blog posts. In any case I will be subscribing to your feed and I hope
    you write again very soon!

  2. Awesome!!!!!!!! superb explaination. i also want to know how to disable the run in background or batch proccessing when a user clicks on a newly created button in a form and it should opens a ssrs report with run in background as disabled…please write an article on tghis.

  3. Hello Peter,

    Excellent Video, your posts helped me a lot…
    I am a student, learning about x++, can you say to me what am i doing wrong? my problem is in the class nameClassContract, when i put extends SysOperationServiceBase, it give me a warning: SysOperationServiceBase does not exist

    What i need to do? Thanks!

  4. Thanks for this awesome blog. All of these posts are so incredibly useful, I really appreciate it and love the care you take to lay these concepts out so clearly.

  5. Hi Peter,
    I have a question about creating a batch job using SysOperationgFramework that I’m wondering if you know the answer to. If I add multiple tasks that operate in parallel, is there any way to make the results of those batch tasks all commit or abort as a single unit? In other words, if I have an error in one task, can I roll the database changes of all of the tasks back? I figured there must be a way to do this but I couldn’t identify any good approach to handling it.

    1. This is a good question. I would need to double check. I believe you should be able to put a ttsbegin and ttscommit around the whole code that creates and runs the multiple threads. Then, if any one of them throws an error, the system should revert all data pack to the state it was in when the ttsbegin line was run.
      I will try to write an article on how to create a multi-threaded (multi-task) batch job, and see if I can test this out.

      1. Thanks! The more I looked into it, I don’t believe it is possible without doing some very awkward and possibly dangerous practices that could open up to infinite loops or deadlocks. What I was able to find out is that each batch task has its own transactional scope and there was no way for me to wrap all of the tasks in a single tts block. In my case, I had to change my approach to allow the tasks to complete independently and move forward with handling the repercussions of this. Thanks again for your great articles!

Leave a Reply

Your email address will not be published. Required fields are marked *

Proudly powered by WordPress | Theme: Baskerville 2 by Anders Noren.

Up ↑