I wanted to write today about why I utilize .NET projects for certain scenarios when developing X++ solutions for D365FO.

How Is This Possible?

How is it possible that you can have two different project types under one solution? I actually wrote about the changes that were happening to the X++ compiler way back in 2017, the change we are most interested in is that X++ code now compiles and generates a .NET CIL (so no p-code intermediary). This allows us to create both X++ and .NET projects within the same solution because they both compile to the same CIL.

How Do We Create a .NET Project in Our X++ Solution (and get it referenced correctly)?

1) On a current X++ solution, right click -> Add -> New Project

2) Select Class Library (.NET Framework)

3) Enter a Project Name and Location, then select .NET Framework 4.7.2 – the reason for this is that if we want to reference any Microsoft DLLs we need to be sure our solution matches the project type and version that the DLLs are built against (which in the case of Microsoft DLLs is .NET Framework 4.7.2)

4) Next we need to create a reference between our X++ project and our .NET project, right click on the References and ‘Add Reference’

5) Next select your .NET project from the Projects tab

6) Now you will see your .NET project is referenced by your X++ project

So Now I Can Reference Microsoft DLLs from the .NET Class?

Yes!

1) Right click on the References tab on your .NET project -> Add Reference

2) Click on Browse -> Then the Browse button

3) Navigate to the PackagesLocalDirectory folder (on my development onebox this is located at K:\AosService\PackagesLocalDirectory) then look for the bin folder. This folder contains the built DLLs that are included with your D365FO instance.

In the example scenario I came up with below you can see I’ve added the Microsoft.Dynamics.AX.Xpp.Support library to my project and then added a ‘using’ statement for Microsoft.Dynamics.Ax.Xpp. This allows me to use the MetadataSupport class in my project to get a listing of all menu item display names and then perform a LINQ statement to find menu items that contain a search term, I then use the JsonConvert class from Newtonsoft.Json nuget package to serialize the object before returning it.

One thing to note here is that by default X++ projects are built against .NET version 4.6, so we need to update this to 4.7.2. To do this we need to find the .rnrproj file which is the X++ project file, open it in a text editor and change the TargetFrameworkVersion from v4.6 -> v4.7.2:

And How Do I Call This .NET Method From X++?

Since we are referencing our .NET project in our X++ solution we can add a using statement to our X++ class to the FpTestNet project and then reference the .NET class and method within our X++ code. Note here that you have to follow the syntax of: <.NetClass>::<.NetMethod>. When we execute the code you can see the correct menu item displays are returned in a JSON format that we can then utilize within our X++ project or return to a service operation endpoint to an external solution.

Why Would We Do This?

There are a couple different reasons I do this within our Fastpath customizations (and advocate others to do this as well):

  • Normally companies have many more .NET developers than X++ developers
    • It is just a simple fact that there are more .NET developers available than X++ developers, now I am not saying that X++ developers aren’t needed (they absolutely are) but for the team I work on I am the sole X++ developer and the rest of the team is .NET developers. Therefore it makes sense for me to try and make this solution as easy as possible for them to develop on as well as debug / troubleshoot so I am not the only one who can perform new development / support if it is needed.
  • NET intellisense seems to always work, X++ intellisense works when it wants to
    • While the X++ intellisense has gotten better over the years, there are still times when I load a solution and no matter what I do intellisense just doesn’t work, I’ve never had that issue in any .Net project I’ve worked on.
  • When using .NET you get all of the ‘goodies’ that go along with it (Nuget packages, LINQ statements on collections, natively supported by DevOps source control)
    • Want to utilize Newtonsoft to serialize objects to JSON before storing them in the database or returning it to a service operation endpoint? Go for it! Want to run a LINQ statement on a collection to filter your results? Go ahead! Want to be able to actually look at lines of code added/removed from a solution instead of looking at XML tags? You got it! All of these options and more are available in .NET and not X++.
  • NET does a much better job with object collections than X++ (especially when you are returning those objects to an external .NET solution).
    • Ok, this might be a personal preference and the fact that I am a .NET dev at heart but I would much rather deal with .NET collections than X++ collections. Microsoft has an entire page dedicated to showing the differences between the collection options between the two. Some key differences include:
      • For object lists, being able to explicitly set the object type (ex: List<myObject> = new List<myObject>)
      • Iterating a list in .NET is a simple ForEach loop, iterating a list in X++ requires you create and maintain a collection iterator
      • Can perform LINQ statements against the collection in .NET

Does this work in every scenario?

No, unfortunately not. There are still cases where you have to write X++ code that cannot be done in .NET. Things like writing SQL statements, creating extensions, and obviously anything that has to be done in the Visual Studio D365FO extension (creating objects, modifying object parameters, etc).

So When Do You Recommend to Use .NET?

For me personally, I try and perform actions in .NET whenever possible for the reasons I listed above.

  • Dealing with large object collections and are
  • Looking to perform business logic on those collection objects
  • Have a need for a .NET nuget package to help with your business logic.

Conclusion

Are there ways to get X++ to do a lot of the things I listed above, absolutely. Are they as simple and straightforward as they are within .NET, I would personally say no. While it may not be right for every scenario, using .NET projects in your X++ solutions may help speed up your time to develop, support, and maintain your D365FO solutions.