Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Runtime Support DLLs from Nuget packages

Discussion in '2017.1 Beta' started by johnseghersmsft, May 5, 2017.

  1. johnseghersmsft

    johnseghersmsft

    Joined:
    May 18, 2015
    Posts:
    28
    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...
    1. Switch your Unity project to use the Experimental .NET 4.6. Close Unity, Restart.
    2. Now create the Visual Studio project files. This will set the .csproj files to target .NET 4.6.
    3. 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.
    4. 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.
    5. 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.
     

    Attached Files:

    rgarrett7 likes this.
  2. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Regarding the pulling packages from NuGet part:

    you could just go to package website in NuGet gallery (for instance, https://www.nuget.org/packages/Microsoft.Azure.DocumentDB/), and click download button. Then, extract the downloaded package using 7-zip, and manually copy the DLLs into your project.
     
    rgarrett7 likes this.
  3. johnseghersmsft

    johnseghersmsft

    Joined:
    May 18, 2015
    Posts:
    28
    I don't see that as being a better solution. The Nuget package manager does download them to a packages directory adjacent to the Assets directory and expands the package. It also makes sure to download any dependency packages (such as the Newtonsoft.Json package mentioned above).

    The error prone part is the manual copying into the project, making sure to get the right DLLs, and recognizing if there are any native runtime support dlls--and making sure to get those copied to the editor directory and to the final output.

    It would be much better if the entire package construct could be imported into the Unity project and Unity could make sure to include and reference the correct primary DLLs and set the Mono engine to look within such packages for the runtime support DLLs.

    This would mean that one doesn't need to modify the Unity installation as is now required in these situations and would mean that the support DLLs could be incorporated into the games Data folder and thus be more easily distributed.
     
  4. GlitchEnzo2

    GlitchEnzo2

    Joined:
    Nov 15, 2012
    Posts:
    5
    Onsterion and rgarrett7 like this.