MapsterMapper / Mapster

A fast, fun and stimulating object to object Mapper
MIT License
4.32k stars 329 forks source link

System.IO.FileLoadException: Could not load file or assembly ... Could not find or load a specific file with .NET 9 preview package #714

Open boylec opened 3 months ago

boylec commented 3 months ago

This is a similar issue to #635 in that an assembly is not being loaded when running Mapster.Tool 8.4.1-pre-1, but the error message is slightly different.

In #635 there is a FileLoadException with "The system cannot find the file specified."

I was seeing this with a different assembly and fixed it using the recommendations from that issue.

Fast forward ->

Then I added System.Text.Json for .NET 9 preview (which targets .NET 8)

Now I'm getting a System.IO.FileLoadException with "Could not load file or assembly ... Could not find or load a specific file"

.csproj:

<PropertyGroup>
   ...
   <TargetFramework>net8.0</TargetFramework>
   <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
   ...
</PropertyGroup>
...
<PackageReference Include="System.Text.Json" Version="9.0.0-preview.5.24306.7" />
<PackageReference Include="Mapster" Version="7.4.1-pre01" />
...

  <ItemGroup>
    <Generated Include="$(ProjectDir)\**\*.g.cs" />
    <GeneratedMappersFolder Include="_mappers" />
  </ItemGroup>

  <Target Name="Mapster" AfterTargets="AfterBuild">
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tool restore" />
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster extension -a &quot;$(TargetDir)$(ProjectName).dll&quot;" />
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster mapper -a &quot;$(TargetDir)$(ProjectName).dll&quot; -o @(GeneratedMappersFolder)" />
    <Message Text="GeneratedMappersFolder: @(GeneratedMappersFolder)" />
  </Target>

  <Target Name="CleanGenerated" BeforeTargets="AfterBuild">
    <Delete Files="@(Generated)">
      <Output TaskParameter="DeletedFiles" ItemName="FilesDeleted" />
    </Delete>
    <Message Text="Files deleted: @(Generated)" />
  </Target>

dotnet-tools.json

  ...
    "mapster.tool": {
      "version": "8.4.1-pre01",
      "commands": ["dotnet-mapster"],
      "rollForward": false
    }
   ...
}

stack trace:

System.IO.FileLoadException: Could not load file or assembly 'System.Text.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. Could not find or load a specific file. (0x80131621)
  File name: 'System.Text.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
   ---> System.IO.FileLoadException: Could not load file or assembly 'System.Text.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.
     at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
     at System.Reflection.Assembly.LoadFrom(String assemblyFile)
     at System.Reflection.Assembly.LoadFromResolveHandler(Object sender, ResolveEventArgs args)
     at System.Runtime.Loader.AssemblyLoadContext.InvokeResolveEvent(ResolveEventHandler eventHandler, RuntimeAssembly assembly, String name)
     at System.ModuleHandle.ResolveMethod(QCallModule module, Int32 methodToken, IntPtr* typeInstArgs, Int32 typeInstCount, IntPtr* methodInstArgs, Int32 methodInstCount)
     at System.ModuleHandle.ResolveMethodHandleInternal(RuntimeModule module, Int32 methodToken, ReadOnlySpan`1 typeInstantiationContext, ReadOnlySpan`1 methodInstantiationContext)
     at System.ModuleHandle.ResolveMethodHandle(Int32 methodToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
     at System.RuntimeType.GetMethodBase(RuntimeModule scope, Int32 typeMetadataToken)
     at System.Reflection.RuntimeCustomAttributeData..ctor(RuntimeModule scope, MetadataToken caCtorToken, ConstArray& blob)
     at System.Reflection.RuntimeCustomAttributeData.GetCustomAttributes(RuntimeModule module, Int32 tkTarget)
     at Mapster.Utils.NullableExpressionVisitor.VisitMember(MemberExpression node) in C:\Projects\Mapster\src\Mapster\Utils\NullableExpressionVisitor.cs:line 130
     at Mapster.Utils.NullableExpressionVisitor.Visit(Expression node) in C:\Projects\Mapster\src\Mapster\Utils\NullableExpressionVisitor.cs:line 50
     at Mapster.Utils.ExpressionEx.CanBeNull(Expression exp) in C:\Projects\Mapster\src\Mapster\Utils\ExpressionEx.cs:line 261
     at Mapster.Utils.ExpressionEx.ApplyNullPropagation(Expression getter) in C:\Projects\Mapster\src\Mapster\Utils\ExpressionEx.cs:line 317
     at Mapster.Adapters.BaseClassAdapter.CreateClassConverter(Expression source, ClassModel classModel, CompileArgument arg, Expression destination) in C:\Projects\Mapster\src\Mapster\Adapters\BaseClassAdapter.cs:line 59
     at Mapster.Adapters.ClassAdapter.CreateBlockExpression(Expression source, Expression destination, CompileArgument arg) in C:\Projects\Mapster\src\Mapster\Adapters\ClassAdapter.cs:line 100
     at Mapster.Adapters.BaseAdapter.CreateBlockExpressionBody(Expression source, Expression destination, CompileArgument arg) in C:\Projects\Mapster\src\Mapster\Adapters\BaseAdapter.cs:line 245
     at Mapster.Adapters.BaseAdapter.CreateExpressionBody(Expression source, Expression destination, CompileArgument arg) in C:\Projects\Mapster\src\Mapster\Adapters\BaseAdapter.cs:line 123
     at Mapster.Adapters.BaseAdapter.CreateAdaptFunc(CompileArgument arg) in C:\Projects\Mapster\src\Mapster\Adapters\BaseAdapter.cs:line 28
     at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg) in C:\Projects\Mapster\src\Mapster\TypeAdapterConfig.cs:line 427
     --- End of inner exception stack trace ---
     at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg) in C:\Projects\Mapster\src\Mapster\TypeAdapterConfig.cs:line 431
     at Mapster.TypeAdapterConfig.CreateMapExpression(TypeTuple tuple, MapType mapType) in C:\Projects\Mapster\src\Mapster\TypeAdapterConfig.cs:line 396
     at Mapster.Tool.Program.GenerateMappers(MapperOptions opt) in C:\Projects\Mapster\src\Mapster.Tool\Program.cs:line 63
     at CommandLine.ParserResultExtensions.WithParsed[T](ParserResult`1 result, Action`1 action)
     at Mapster.Tool.Program.Main(String[] args) in C:\Projects\Mapster\src\Mapster.Tool\Program.cs:line 19

This .dll can be found in my /bin/Debug/net8.0 folder at the time that I run Mapster.Tool.

I checked the assembly version on the generated .dll as well using powershell and everything matches for what the tool is trying to load (the assembly name, version, and public key)

Note: I censored absolute paths on my local hard drive with '...'

PS .../bin/Debug/net8.0> ([system.reflection.assembly]::load([System.IO.File]::ReadAllBytes(".../bin/Debug/net8.0/System.Text.Json.dll"))).FullName
System.Text.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51

Any ideas? I'm flummoxed.