MapGuide RFC 154 - .net Core support
This page contains a change request (RFC) for the MapGuide Open Source project. More MapGuide RFCs can be found on the RFCs page.
|RFC Template Version||(1.0)|
|Submission Date||1 Dec 2015|
|Last Modified||1 Dec 2015|
|Assigned PSC guide(s)||(when determined)|
|Voting History||(vote date)|
This RFC proposes to add a MapGuide API wrapper that supports .net Core
The next version of ASP.net is multi platform. Our current .net wrapper is windows-only and will not work in this new cross platform world.
Such support in this new cross-platform .net requires a new wrapper that can target it
We'll add a new MapGuideDotNetCoreApi project to the WebTier solution. This will use the SWIG configuration that was for the .net API before the assembly split (RFC68), a single monolithic glue dll and .net assembly. The current split assembly configuration is not possible due to use of reflection APIs that do not exist in the .net core API surface.
MapGuideDotNetCoreApi will also have a Linux target for building this glue library
For the .net core wrapper assembly, it will be built using the DNX/project.json system
In the .net Core world, the final build artifact and unit of distribution is not an assembly (or set of assemblies), but a NuGet package.
For the simplest packaging and deployment story, our .net wrapper should exist as a single NuGet package that bundles all the necessary unmanaged libraries for all the platforms we intend to support:
- Windows (x86)
- Windows (x64)
- Linux (x86)
- Linux (x64)
Supporting a true cross-platform .net wrapper presents a unique build challenge in that it is difficult to have all unmanaged/glue libraries for Windows and Linux present in a single build run.
Based on current guidance, it is suggested for Linux that the necessary glue libraries should be assumed to be already present on the system, so nothing is bundled into the nuget package for Linux in this respect.
The build strategy for this wrapper therefore is as follows:
- Build MapGuide for Windows (x86|x64) as normal
- As part of each windows build, collect and archive the necessary artifacts (the SWIG-generated wrapper source and the unmanaged/glue libraries) needed for the .net wrapper to function
- Store/upload these archived artifacts to a staging area
Then the build process for the wrapper itself is:
- Download/extract the various archives into their respective /runtimes/$PLATFORM/native subdirectory. Such directories will be included in the final nuget package.
- dnvm use [latest version] -r coreclr
- dnu pack --configuration Release
On Windows, we will be bundling the full set of unmanaged libraries (the SWIG glue library and its dependencies). DNX can recognize and load the correct unmanaged libraries from the /runtimes/$PLATFORM/native subdirectory of the nuget package.
On Linux, the SWIG glue library itself as the other dependencies are assumed to reside in a well-known location (/usr/local/mapguideopensource-3.1.0/webserverextensions/lib), which an can be appended to LD_LIBRARY_PATH before running your MapGuide application with DNX.
.net - Native String Marshaling on Linux
MapGuide uses std::wstring/wchar_t for all of its APIs that accept and return strings. wchar_t has a different size on Linux than it does on Windows, meaning the strings that travel across the .net - native boundary will turn into garbage due to the size difference of wchar_t. To rectify this, the SWIG typemaps for .net core will use the same string conversion logic as the SWIG typemaps for Java, using the UnicodeString helper class in the MdfModel library to:
- Convert UTF-16 input strings from .net into UTF-32 wide strings for the wrapped API call
- Convert UTF-32 wide strings from a wrapped API call into UTF-16 strings for returning to .net
This API wrapper will be an out-of-band package. It will not be included with the Windows/Linux installer packages. The delivery channel is strictly NuGet. Like our current NuGet packages, the developer is expected to use the same matching version of the NuGet package for the particular version of MapGuide they wish to target.
Although .net Core also supports Mac OSX and FreeBSD, our .net wrapper does not and is not supported on these platforms.
This RFC only affects ASP.net 5 under the CoreCLR profile. ASP.net 5 under the full .net Framework can use the existing NuGet package offerings.
The canonical deployment strategy of ASP.net 5 applications is to host it on the Kestrel HTTP server and reverse-proxy to it from the front-facing web server:
- On Windows, this is IIS with the HttpPlatformHandler extension
- On Linux, this is any http server with reverse proxying capabilities. Although the official documentation recommends nginx as the front-facing server, our deployment story on Linux will be using the bundled Apache httpd server with mod_proxy to reverse proxy into Kestrel.
For Linux, the usage and availability of the MapGuide API for .net core will be restricted to any Linux distribution where binaries exist for the CoreCLR. Currently, this is only Ubuntu 14.04 64-bit, which is the version of Ubuntu we intend to support for this release of MapGuide. CoreCLR is not available for Ubuntu 14.04 32-bit.
The API surface of the .net core wrapper is almost identical to the one for the full .net framework with a few small differences:
MgColordoes not have a constructor or implicit operators that accept
System.Drawingdoes not exist in .net Core.
- Constructor now optionally takes a
System.Collections.Generic.IEnumerable<String>instead of a
- implicit conversion operators to/from
System.Collections.Specialized.StringCollectionhave been removed
System.Collections.Generic.IList<String>in line with other collection proxy classes
- Constructor now optionally takes a
We'll port the existing .net web tier test suite over to CoreCLR/DNX and verify the full test suite passes on both Windows and Linux
Funding / Resources