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:
-
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:
We only
need the one
with 2 parameters.
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
Een reactie posten