ぷろじぇくと、みすじら。

Blazor Web Assembly を publish すると AssemblyResolutionException でエラーとなる

Created at:

現象

Visual Studio からの発行や dotnet publish -c Release などを実行したとき、IL Linker 実行中に以下のような AssemblyResolutionException がスローされます。

  Fatal error in Mono IL Linker
C:\Users\Tomoyo\.nuget\packages\microsoft.aspnetcore.components.webassembly.build\3.2.1\targets\Blazor.MonoRuntime.targets(326,5): error : Unhandled exception. Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'SQLitePCLRaw.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1488e028ca7ab535' [C:\Users\Tomoyo\Source\Repos\BlazorApp6\BlazorApp6\BlazorApp6.csproj]
   ---> Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'SQLitePCLRaw.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1488e028ca7ab535'
     at Mono.Cecil.BaseAssemblyResolver.Resolve(AssemblyNameReference name, ReaderParameters parameters)
     at Mono.Linker.AssemblyResolver.Resolve(AssemblyNameReference name, ReaderParameters parameters)
     at Mono.Linker.LinkContext.Resolve(IMetadataScope scope)
     at Mono.Linker.LinkContext.Resolve(IMetadataScope scope)
     at Mono.Linker.LinkContext.ResolveReferences(AssemblyDefinition assembly)
     at Mono.Linker.Steps.LoadReferencesStep.ProcessReferences(AssemblyDefinition assembly)
     at Mono.Linker.Steps.LoadReferencesStep.ProcessAssembly(AssemblyDefinition assembly)
     at Mono.Linker.Steps.BaseStep.Process(LinkContext context)
     at Mono.Linker.Pipeline.ProcessStep(LinkContext context, IStep step)
     at Mono.Linker.Pipeline.Process(LinkContext context)
     at Mono.Linker.Driver.Run(ILogger customLogger)
     at Mono.Linker.Driver.Execute(String[] args, ILogger customLogger)
     at Mono.Linker.Driver.Main(String[] args)

原因

IL Linker は依存しているアセンブリ参照をすべて検索して、不要な IL を削っていくというビルドステップです。

この例外(エラー)は依存先のアセンブリを探しているときにアセンブリが見つからなかった場合に発生するもので、通常 NuGet でパッケージ参照されているものに対しては発生しません。

しかし依存パッケージの作り次第では例外が発生する場合があります。例えば Microsoft.CodeAnalysis.Workspaces.Common のようなパッケージを参照すると発生します。

これは Microsoft.CodeAnalysis.Workspaces.CommonSQLitePCLRaw.bundle_green パッケージを PrivateAssets="all" として参照しているため、実際のパッケージにはパッケージ参照として SQLitePCLRaw.bundle_green が含まれないことでアプリケーションから参照したときにパッケージが解決されないのでアセンブリが見つからないということが発生します。

つまりパッケージの依存としては扱わないもののアセンブリを参照はあるという状況で発生します。必須ではないパッケージなどの場合にはこういった構成になります。

解決方法

解決方法としては次の2つの方法があります。

1. 必要なパッケージをプロジェクトで参照する

見つからないといわれているアセンブリが含まれているパッケージをプロジェクトから参照します。

2. IL Linker を無効にする

SQLitePCLRaw.bundle_green のようなものは参照してもエラーとなるのでそういった場合には IL Linker 自体を無効にします。

https://docs.microsoft.com/ja-jp/aspnet/core/blazor/host-and-deploy/configure-linker?view=aspnetcore-3.1

<PropertyGroup>
  <BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking>
</PropertyGroup>