I just went through the experience of getting the .NET SDK for Azure’s DocumentDB working inside of Unity 2017.1b3. I ran into several issues, most of which have workarounds, but which could be made much better (or perhaps I found the hard ways :)).
First, let me detail how to get this working in case someone finds this on a search and they want to know how to do it…
- Switch your Unity project to use the Experimental .NET 4.6. Close Unity, Restart.
- Now create the Visual Studio project files. This will set the .csproj files to target .NET 4.6.
- Use the Nuget package manager to download the Microsoft.Azure.DocumentDB .NET client library. This will also download the Newtonsoft.Json package. These will be downloaded to a packages directory where they will do Unity no good.
- Search for DLLs in the packages. You will find two dlls in subdirectories named lib/net45. Copy these (Microsoft.Azure.Documents.Client.dll and Newtonsoft.Json.dll) into your Assets/Plugins directory. There are also similarly-named XML documentation files, I copy those too.
- There are also two native DLLs located in runtimes/win7-x64. Copy these files (DocumentDB.Spatial.Sql.dll and Microsoft.Azure.Documents.ServiceInterop.dll) to your Unity/Editor directory or else you won’t be able to run the project in the editor.
That will get you to the point where you can code against the SDK and it will compile within Unity.
However, there are a couple of issues documented in the bug (Case 907956) TypeLoadException initializing DocumentDB DocumentClient object and problems with (dynamic).
First the “easy” one: If you try to build a project in Visual Studio and it uses the dynamic type, it will fail to build. This is because the project needs a reference to Microsoft.CSharp and the .csproj files built by Unity doesn’t have them. The attached file ProjectFileHook.cs is an editor script (just put it somewhere in an Editor folder in your project) that will insert the appropriate reference into all of the .csproj files generated.
The other problem is that Mono throws a TypeLoadException when initializing the DocumentClient object. It reports not being able to load a type number rather than a name. Another person I reached out to who knows more about how assemblies are packaged found that the type referenced is System.Diagnostics.Eventing.EventProviderTraceListener, which is normally supplied by System.Core
in the .NET framework. Unfortunately, the Mono version of System.Core doesn’t implement this type. The person who tracked this down provided me with a patched version of the DLL that eliminates the one place this was used and unblocks me, but doesn’t solve the problem in general (especially since patching the DLL breaks the strong-name).
Now we get to the question in this post: How to best support packages like this?
As you can see above, steps 4, and 5 involve a lot of manual operations that are very error prone. I only spotted #5 because of noticing the long string of “Fallback handler could not load library…” lines in the log file when looking for Microsoft.Azure.Documents.ServiceInterop.dll.
It seems to me like we need:
- A better way to pull packages from NuGet
- A place to put runtime DLLs that are support DLLs for the DLLs that provide the APIs we use. In the case of the runtime DLLs above, I needed to put them in the Editor directory (or I suppose one of the directories searched by Mono’s fallback method), and they would also need to be manually packaged in the install directory of the final game executable.
3058103–229670–ProjectFileHook.cs (1.39 KB)