Getting started with NAV and .Net Interop – Part 2



Long overdue

So here’s Part 2. It took me some time to get off the ground since I had to rebuild my VM-infrastructure. I’m now running the database on a SQL 2012 VM with the NAV 2013 R2 Update 7 Service, clients, webclients and help-server running on a separate RDS Server VM. Each powered by an awe-inspiring 1 GB of Memory J. Thanks to BizSpark for the licenses !

Coding conventions and other disclaimers

I’m going to preface these articles with a disclaimer that my code uses the code formatting as customary at my employer Edan Business Solutions without whom this article would not have been possible. It’s easiest for me and helps differentiate variables from keywords. I don’t mind discussing the finer points of this decision in the comment section, but know that it is unlikely to change my opinion (as my dear wife can attest, I’m quite stubborn on a lot of topics J).
Also, .Net Interop will only work when running in an RTC-context (this includes webservices). The Classic Client cannot use variables of the type DotNet.

General Method

So you read Part 1 and you’re all fired up (I’ll settle for lukewarm too J). You want to “try some .Net in your NAV”. But what? How?
It all starts with the what? Something you need to develop. Import a file, parse a date from a specific locale, send an e-mail, or download a file.
We’ll tackle the “how” along with our first “what”.

Build a file path from a folder and filename

Scouting ahead

We’re going to start real simple with the example of the previous article. How did we get there? In NAV we did the following with all the inherent problems we discussed earlier:

lv_FilePath := lv_ImportPath + '\' + lv_Filename;

So as is often the case, you Google for a solution to your problem. You can look for C# or VB.Net examples depending on what language you find easiest to read. I prefer C#.
So we Google “c# combine folder and filename”:



















Right off the bat the examples look promising:
-          Stack Overflow is always a good resource on how to do things the best way.
-          The MSDN Pages often have useful examples.
We get the following code snippet:

string combined = Path.Combine(dir, fileName);

Looks like what we need. But how translate that in NAV?
Well, apparently “Path” is a static reference to the class Path (since we don’t see it being declared). When we go to the MSDN Page we can see that it has several “overloads” for the Combine method:




For NAV 2013 (R2) make sure you select the .Net 2.0 or 4.0 version (not that it matters with this method, but it’s a good practice to ensure you’re looking at the relevant version):



In the end, what we NEED is the assembly (the .DLL) the method/class is located in:








Digging in

In NAV, you now create a DotNet variable and lookup its subtype:









In the Type List you open the Assembly lookup:








In the Assembly List you choose the tab “.Net” (the NAV tab contains Addins in the DevClient’s Addins folder) and select the assembly. The choice of “Processor Architecture” here is largely irrelevant. If the variable is going to be used on the service (per default) it needs to have an x64 or MSIL variant. If it’s going to be used on the client (almost never) it needs to have an x86 or MSIL variant. Either way, for coding it does not matter since NAV will chose this at runtime. Pick any one if you have multiple choices:



Back in the Type List scroll down to System.IO.Path and select it:




















We end up with the subtype “System.IO.Path.'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'”. Notice that the subtype contains:
-          The full classname “System.IO.Path”
-          The assembly name “mscorlib”
-          The Version “2.0.0.0”. This will usually correspond with a .Net framework version, but if you use assemblies outside of the framework it could be anything.
-          The culture “neutral”. This is often inconsequential.
-          The unique key of the assembly “b77a5c561934e089”.
Notice, again, there is no distinction of processor architecture in the subtype.

Where does the pointy bit go again?

So we have our variable declared. Remember when we noticed Path was being used statically? This means several things:
-          Mostly it means you don’t need to instantiate it to use its members.
-          It also means that any members it DOES have are shared across the current AppDomain. Mostly this can be interpreted as “across your program”. You can compare them with Single-Instance Codeunits and even use them in the same way.
-          Usually however, static classes try not to have any properties, so they’re mostly used as libraries for handy methods.

Like in our example.

Not having to instantiate the variable doesn’t mean we don’t have to make the variable. This is how NAV differs from C#. You can’t just write Path.Combine. Instead our little code snippet is now written as:

lv_FilePath := ldn_Path.Combine(lv_ImportPath,lv_Filename);

If you write that bit using the C/AL Symbol Menu you can browse around and see several other “interesting” functions that I’ll leave to you to explore:



So long folks

So that’s it for Part 2. It took some time since I didn’t have

Reacties

Populaire posts van deze blog

Getting started with NAV and .Net Interop – Part 4

Getting started with NAV and .Net Interop – Part 3

Getting started with NAV and .Net Interop – Part 1