In the previous article, I explained what Chain Of Command is, and how to use it in Microsoft Dynamics 365. I provided a basic example of Chain of Command, and explained what pieces are required. In this article we will look at an example of how to implement Chain Of Command Form DataSource field methods.
Objects That Can Use Chain Of Command
As a review, there are several different objects in Microsoft Dynamics 365 that can use Chain Of Command. I will list the most common here.
- Classes
- Tables
- Forms
- Datasource on a form.
- Data field on a form.
- Control of a form.
- Data entities
Chain of Command Rules
Before providing an example of using Chain of Command for form datasource field methods, I wanted to first review the requirements that all Chain Of Command classes must follow. If you do not follow these rules, the compiler will not recognize your new class as a Chain of Command class.
- The name of the new class you create must end with the text ‘_Extension’.
Pro Tip: Because classes and forms and tables are often named the same thing, and each can be modified using Chain of Command, I have found it helpful to put the object type in the name of the Chain of Command class. This is not required, however, it will make your code more readable. I recommend using a format like this: <BaseObjectName>_<ObjectType>_Extension - The keyword ‘final’ must be used in the class definition line.
- The class needs to have the attribute
[ExtensionOf(classStr(<NameOfBaseObject>))]
The “classStr” text above will change depending on the type of base objecting you are extending. I will explain more later. - Add the method definition the exact same way it appears in the base class.
- Your code must call the base class’s method inside your extension method using the ‘next’ keyword. Using the above example you need to have this line.
var s = next doSomething(arg);
Using The Right Global Function
All of the rules above apply for all uses of Chain Of Command. However, the function you use within the ‘ExtensionOf’ method above will be different based on the type of object you are extending.
While you could enter a string inside the ExtensionOf function, this would not be following best practice. The reason why we want to use a global function is because if the name of the base object ever changes name, using a global functional will cause a compile error to return. This will inform the developer that they need to make a change. Whereas if you use a string directly, you will not get a compile error, and your Chain of Command class will no longer work.
Let’s go through each type of global function we can use inside of the ExtensionOf function.
- When extending a class, use classStr(<NameofBaseClass>)
- When extending a table, use tableStr(<NameOfBaseTable>)
- In the case of a form, use formStr(<NameOfBaseForm>)
- When extending a form Datasource use formDataSourceStr(<NameOfBaseForm>,<NameOfDataSource>)
- When extending a form Data field, use formDataFieldStr(<NameOfBaseForm>,<NameOfDataSource>,<NameOfField>)
- For a form control, use formControlStr(<NameOfBaseForm>,<NameOfControl>)
- When extending a data entity, use tableStr(<NameOfBaseDataEntity>)
Extend Form DataSource field methods
Do you have code that you want to run when the value of a field on a form is changed? One the most common methods you might want to add to a Form DataSource field method, is the ‘modified’ method. If you need this code on a base Microsoft form, you need to use Chain Of Command to add this functionality to the method.
Typically putting code on the datasource field is better than putting code directly on the control. This way if the same field is used in multiple places on the form, all of them will call this same method.
[ExtensionOf(formDataFieldStr(SalesTable, SalesLine, ItemId))]
final class SalesTable_SalesLineItemId_Extension
{
public void modified()
{
FormDataObject formDataObject = any2Object(this) as FormDataObject;
FormDataSource formDataSource = formDataObject.datasource();
SalesLine salesLine;
next modified();
salesLine = formDataSource.cursor();
salesLine.Name = InventTable::find(salesLine.ItemId).itemName();
}
}
Conclusion
Anytime you have code in a base Microsoft form DataSource field, you can use Chain Of Command to add additional code before or after the call to the base method. You still always have to call the base method. But you can change how the method works.
- When you put code before calling the base method, you can change the values that are sent in as parameters to the base method. This can cause different branches inside the base method to be run or not run.
- After receiving the response value from the base method you can change this value before returning it to the calling method. This can allow you to change what code paths the calling method takes.
- By adding code after the call to the base method, you can add additional validation, functionality, and actions that should occur anytime the method is called.
Hi Peter Ramer
Thank you for the content and videos on MS AX it is really helpful to me.
I am a beginner level in AX and your giving really good explanation in your videos. I watched your videos on chain of command(COC)the content is really good and as a beginner I am requesting you to please make a video on coding part(COC)with really in depth explanation to point to point of code. I am unable few lines of code for example getting “FormDataObject” and getting currently selected records in “formcontrol” and “FormDataSourceField”.if possible please make a video on SSRS reports with in depth explanation of coding .Please consider my request.
Thanks for the comment. I can do that! I will add those to the list.
I have the same request please, Peter. Your videos are really very helpful. Thank you. 🙂
Please make a video on SSRS report.
Nice explanation.
I have a query where I want to call a custom method written on form datasource from form data Field (datasource field) modified method.
I have tried different ways but resulting in an error.
Appreciate if there is any solution for this.
You can try writing_ds.();
See if that helps. Basically add underscore then the letters ds to the end of the datasource name, then add a dot. I think that should show you all of the methods on the datasource specifically.
Hi Peter, Nicely explain…
I have one query. As I know that the Private method is not supported by CoC.
If suppose, i need required some modifications on standard class in Private method as per the business requirements then how will i achieve this ?
Kindly guide me please.
Thanks!
Hi Arpan. If the method is private, and you can’t do CoC on that method look to see if there is a method that calls that first method that isn’t private. You could then do CoC on that one.
It isn’t ideal, but it really is your only option. You might need to undo some changes that the calling method does, because you weren’t able to put your custom code exactly where you wanted to on the called method. But sometimes this still works.
So in short, you just have to find another method that does allow CoC to make your changes.
Thanks Peter, for the answer.
1. As you said “If the method is private, and you can’t do CoC on that method look to see if there is a method that calls that first method that isn’t private. You could then do CoC on that one.”
You mean to say , for example –
Standard Class // need to create an extension for this class
{
Private calc() // Private method
{
// As per my question, I need requirement to add some code but this is not possible through CoC
}
Public Sum() // Public method
{
// Private method
this.calc(); // here we can use CoC for this private method as per the requirement. If it exist in some another method which is not private.
}
}
Is my assumption is correct?
2. Another solution I think, can we create an” Extendibility service request ” to MS for the solution?
Kindly elaborate please.
Thanks!
Yes. That is correct. In your example the method named calc is private. But the method named Sum is public and it calls calc. So you can do CoC on the method named Sum.
You can make an extensibility request to Microsoft. That would be good too. But it might take them until the next version to made changes. And you might need a fix sooner.
If Microsoft does make the private method public sometime in the future, you can always change your code.
Hi Peter Ramer
Another solution is:
Can we create a new class and implement the same business logic as public method, which is present in Private method on the standard class.
for example –
Custom class
{
public calc ()
{
// here I like to add the same business logic which is present in standard class in Private calc().
}
}
So, that we can avoid the private method if required any modifications with CoC.
I think this is some tricky solutions, but we can try this also.
Kindly advise please
Yes. You can do CoC on the public method.
Thanks Peter, for the response.
Thank you Peter Ramer for the update. Really appreciate!