MapsterMapper / Mapster

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

Mapster.Tool throwing System.IO.FileNotFoundException when using version 8.4.1 #635

Closed stagep closed 9 months ago

stagep commented 9 months ago

Since upgrading Mapster.Tool from 8.4.0-pre06 to 8.4.1, any mapping that references a type from a nuget package will throw an exception: E.g. Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Google.Protobuf, Version=3.24.3.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604'. The system cannot find the file specified.

I am using the latest version of Mapster (7.4.1-pre01). I have tested and got the exception in .Net 7 and .Net 8 projects.

I am using Google.Protobuf as an example of a nuget package and using the example type of ByteString

In the project file i have `

` My mapping configuration is: ```using Google.Protobuf; using Mapster; namespace MapsterToolsException; public class MapsterConfiguration : IRegister { public void Register(TypeAdapterConfig config) { config.ForType().MapWith(d => d.ToArray()); } } ``` You do not need to have any mappers defined to get the exception. There is a workaround. Manually copying the Google.Protobuf.dll to the build folder (e.g. bin/Debug/net7.0) will eliminate the exception.
stagep commented 9 months ago

More details of the exception:

1>Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Google.Protobuf, Version=3.24.3.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604'. The system cannot find the file specified.
1>File name: 'Google.Protobuf, Version=3.24.3.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604'
1>   at MyProject.MapsterConfiguration.Register(TypeAdapterConfig config)
1>   at Mapster.TypeAdapterConfig.Apply(IEnumerable`1 registers) in C:\Projects\Mapster\src\Mapster\TypeAdapterConfig.cs:line 752
1>   at Mapster.TypeAdapterConfig.Scan(Assembly[] assemblies) in C:\Projects\Mapster\src\Mapster\TypeAdapterConfig.cs:line 731
1>   at Mapster.Tool.Program.GenerateMappers(MapperOptions opt) in C:\Projects\Mapster\src\Mapster.Tool\Program.cs:line 66
1>   at CommandLine.ParserResultExtensions.WithParsed[T](ParserResult`1 result, Action`1 action)
1>   at Mapster.Tool.Program.Main(String[] args) in C:\Projects\Mapster\src\Mapster.Tool\Program.cs:line 19
carumsoft commented 9 months ago

I'm new to Mapster and i had similar problem. You can not use AfterTargets="AfterBuild" path. This is not working.

I'm using on demand path with "dotnet build -p:CopyLocalLockFileAssemblies=true"

  <Target Name="Mapster">
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet build -p:CopyLocalLockFileAssemblies=true" />
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tool restore" />
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster model -a &quot;$(TargetDir)$(ProjectName).dll&quot;" />
    <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;" />
  </Target>
stagep commented 9 months ago

Thanks for the pointer. I was able to resolve by adding `

true

` to my project file and it now works as this copies the libraries referenced from the nuget packages to the build folder and the Mapster.Tool process can now find the necessary files. I did not modify anything else.

For future reference, this was a client side library so by default, the nuget files are not copied to the build folder.

andrerav commented 9 months ago

I'm sorry for your troubles @stagep, and thanks for the help @carumsoft. I think that this should be added to the documentation in case other users are experiencing this. @stagep Is it possible for you to share more details on how your csproj is set up now?

stagep commented 9 months ago

The project is a class library referenced by MAUI and Blazor WASM projects.

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Google.Protobuf" Version="3.24.3" />
        <PackageReference Include="Mapster" Version="7.4.1-pre01" />
    </ItemGroup>

    <Target Name="Mapster" AfterTargets="AfterBuild">
        <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tool restore" />
        <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster mapper -a &quot;$(TargetDir)$(ProjectName).dll&quot;" />
    </Target>
</Project>

Mapster.Tool 8.4.1-pre01 is installed.

andrerav commented 9 months ago

Awesome, thank you very much. I've added both of your workarounds to the wiki here: https://github.com/MapsterMapper/Mapster/wiki/Mapster.Tool#troubleshooting

boylec commented 1 month ago

I have a similar issue with the same versions of tooling but slightly different exception message for System.IO.FileNotFoundException, see referenced issue.