Skip to content

Assembly loading

Rico Suter edited this page May 14, 2018 · 60 revisions

When a Swagger specification is generated with either the

then the selected assemblies are loaded in a separate AppDomain (when host is running on full .NET) or AssemblyLoadContext (running on .NET Core) to avoid assembly conflicts.

This is required to produce the Swagger spec outside of a running ASP.NET process, i.e. it can be generated externally (e.g. via command line). However, this process may be tricky - for example because some required DLLs are missing or NSwag runs with newer versions of libraries than the loaded Web API assembly. To avoid problems with this process, you should use the NSwag binary of the same type as the assembly to load.

NSwagStudio internally starts one of the NSwag command line binaries depending of the selected Runtime (the default uses the same runtime as NSwagStudio - i.e. WinX64 or WinX86). With the CommandLine package, you can select the runtime with the /runtime:WinX64 setting. The package MSBuild provides different variables to access a specific binary.

This page gives you some tips how to properly configure NSwag to load assemblies:

  • WebApiAssemblyToSwaggerGenerator class: Uses AppDomain or AssemblyLoadContext depending in which environment (full .NET, .NET Core) it is running
  • NSwagStudio: NSwagStudio starts one of the NSwag command line binaries, selected with the Runtime setting
  • NSwag.NPM: AppDomain or AssemblyLoadContext via /runtime:NetCore20 switches
  • NSwag.MSBuild: AppDomain or AssemblyLoadContext via different ${NSwagExe} properties

Available runtimes (set via /runtime:WinX64):

  • Default: Uses the runtime of the current process with no checks
  • WinX64: Full .NET, x64 (default in NSwagStudio)
  • WinX86: Full .NET, x86
  • NetCore10: .NET Core 1.0
  • NetCore11: .NET Core 1.1
  • NetCore20: .NET Core 2.0
  • NetCore21: .NET Core 2.1
  • Debug: Creates a new AppDomain in the current process (full .NET only, e.g. NSwagStudio, runtime will be WinX64 or WinX86)

The important settings for loading assemblies are:

  • AssemblyPaths: Specifies the paths to DLLs (usually only one) where the controller types are found. All required dependent assemblies are looked up in the same directory or subdirectories.
  • ReferencePaths: Specifies paths to directories where additional dependent assemblies are looked up.
  • ConfigurationPath: The path to the app.config or web.config, this is usually not needed but may avoid problems if binding redirects are needed

.NET Core

Important: Choose the correct Runtime in NSwagStudio or use the /runtime:NetCore20 setting with the NSwag.NPM package.

TODO: Update wiki to use this much better technique instead of dotnet publish: https://github.com/RSuter/NSwag/issues/1159#issuecomment-363886104

If some DLLs are missing because they were not published and thus not available, first try to add %USERPROFILE%/.nuget/packages to the ReferencePaths setting (NuGet cache locations on other platforms).

.NET Core 2.0

Because a ASP.NET Core 2.0 is not published with all required DLLs, you have to add the following config to your .csproj:

<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>

This makes the compiler output all required DLLs to the output directory. If you want to fully publish only once, use:

dotnet publish --self-contained --runtime your_runtime

See the .NET Core Runtime IDentifier (RID) catalog for more information about runtimes.

.NET Core 1.1

First publish your project with dotnet publish, then add the DLL with the controllers to the AssemblyPaths from the publish output directory.

.NET Core 1.0

To generate the Swagger specification for a controller in a .NET Core assembly, follow these steps:

  1. Right-click your ASP.NET Core Web API project and select "Publish..." to publish your project to the file system (publishes all necessary .dll to your file system).
  2. Conigure NSwag (the Web API assembly input settings):
    • AssemblyPath: C:\Projects\MyApplication\bin\Debug\MyApplication.dll
    • ReferencePaths:
      • C:\Program Files\dotnet\shared\Microsoft.NETCore.App\1.0.0
        • Use the same .NET Core Framework version as your application
        • This directory contains the .NET Core system assemblies in the x64 (this is why the host must be running in x64 mode)
      • C:\Projects\MyApplication\bin\Release\PublishOutput
    • ConfigurationPath (path to Web.config): C:\Projects\MyApplication\web.config
    • Set IsAspNetCore setting to true

Sample configuration in NSwagStudio for a .NET Core Web API assembly:

Troubleshooting

Could not load type X from assembly Y

  • Check if the assembly Y is in the output directory or in one of the directories of ReferencePaths, otherwise use dotnet publish to publish all required DLLs (also try --self-contained for .NET Core 2.0)
  • Try adding the full path to the missing DLL in AssemblyPaths BEFORE the DLL with the controller classes:

  • Try adding C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.0.0 to ReferencePaths (replace "2.0.0" with your .NET Core version)