Skip to content

Conversation

@DocSvartz
Copy link

No description provided.

@DocSvartz DocSvartz requested a review from andrerav October 31, 2025 17:19
@DocSvartz DocSvartz changed the title Updated version numbers to 9.0.0-pre02. Updated version numbers to 9.0.0-pre02. + net 10.x Nov 17, 2025
@DocSvartz DocSvartz changed the title Updated version numbers to 9.0.0-pre02. + net 10.x Updated version numbers to 9.0.0-pre02. + net 10 Nov 17, 2025
@DevTKSS
Copy link
Collaborator

DevTKSS commented Nov 26, 2025

@andrerav I can not use Mapster because its requiring net7:

Framework: 'Microsoft.NETCore.App', version '7.0.0' (x64)

would you maybe check if you are able to merge this (hopefully fixing) PR ?

@stagep
Copy link

stagep commented Nov 26, 2025

@DocSvartz
Copy link
Author

@DevTKSS If you are using net 8.0 or net 9.0, you can try use Mapster 9.0.0-pre01.
Include Breaking changes after 9.0.0-pre01 to the Mapster library are not planned.

@DevTKSS
Copy link
Collaborator

DevTKSS commented Nov 27, 2025

@DocSvartz I am using the latest pre release that's available for all nugets and tool too, but the tool keeps failing with telling me I would need to install the net7 runtime workload which shouldn't be required.
As there is no simple source generator package available as replacement alternative seems like I will have to search a different NuGet or dotnet tool for mapping or keep writing Dtos 🤷

@stagep
Copy link

stagep commented Nov 27, 2025

Are you using Mapster and/or Mapster.Tool? As @DocSvartz mentioned, older versions supported .Net 7. The worse case scenario is forking and adding back in .Net 7. We are here to help you find a solution / workaround.

@DevTKSS
Copy link
Collaborator

DevTKSS commented Nov 28, 2025

@stagep I figured it out, but the Wiki was not very helpfull in this 😅 Could you at least update this?
Just in case you might want to improve the User Expirience, feel free to share this setup in your docs with your other users 👍

A part of the problem was also that, while you "just" used the &quote; for " I would have prefered a small Note box to not get an headache by not seeing this small difference 😅

I additionally installed it globally, but more out of always typing -g for the other dotnet tool I am using 😄
dotnet-tools.json:

{
  "version": 1,
  "isRoot": true,
  "tools": {
    "mapster.tool": {
      "version": "9.0.0-pre01",
      "commands": [
        "dotnet-mapster"
      ],
      "rollForward": true,
      "allowPrerelease": true
    }
  }
}

This is what I came up with using Directory.Build.targets alongside with minimal csproj and Directory.Packages.props usage as my Solution uses CPM:

Directory.Packages.props

  <ItemGroup Label="Mapping">
    <PackageVersion Include="Mapster" Version="9.0.0-pre01" />
    <PackageVersion Include="Mapster.DependencyInjection" Version="9.0.0-pre01" />
    <PackageVersion Include="Mapster.Async" Version="9.0.0-pre01" />
    <PackageVersion Include="Mapster.Immutable" Version="9.0.0-pre01" />
    <PackageVersion Include="Mapster.EFCore" Version="9.0.0-pre01" />
  </ItemGroup>

Directory.Build.targets

<Project>
  <!--
    Mapster integration targets.
  
    Mapster integration targets.
    Usage:
      1) Run one-time setup (executes dotnet tool restore in repo root):
         msbuild -t:MapsterSetup
      2) Enable per-project automatic Mapster generation by adding to the project's .csproj:
         <PropertyGroup>
           <MapsterEnabled>true</MapsterEnabled>
         </PropertyGroup>
    3) Optionally, specify the Mapster generated files path pattern e.g. if you want to see the files in the project directory:
        <ProjectProperties>
          <MapsterPath>$(ProjectDir)**\mapster\**\*.g.cs</MapsterPath>
        </ProjectProperties>

        And include the following ItemGroup to expose the generated files in the project:
        <ItemGroup Label="Include Mapster Generated Files" Condition="'$(MapsterEnabled)' == 'true' and Exists('$(BaseIntermediateOutputPath)mapster')">
          <Compile Remove="$(MapsterPath)" />
          <None Include="$(MapsterPath)">
            <Link>mapster-generated/$(RecursiveDir)%(Filename)%(Extension)</Link>
            <Visible>true</Visible>
          </None>
        </ItemGroup>

    4) Build the project. If MapsterEnabled is true and the project includes a net9.0 target framework, Mapster code generation will run after build.
       as the code generated is not runtime-specific, it will be generated once per project, not per TFM.
       This way you can also use the generated files in multiple TFMs e.g. net10.0 while dotnet-mapster only supports up to net9.0 currently.
         -->
  <Target Name="MapsterSetup">
    <!-- Run tool restore in repository root (parent of /src). Only report on failure to avoid noise. -->
    <Exec WorkingDirectory="$(MSBuildThisFileDirectory).." Command="dotnet tool restore" Condition="Exists('$(MSBuildThisFileDirectory)..\.config\dotnet-tools.json')" ContinueOnError="true">
      <Output TaskParameter="ExitCode" PropertyName="MapsterSetupExitCode" />
    </Exec>
    <Error Text="MapsterSetup: dotnet tool restore failed (exit code $(MapsterSetupExitCode))."
           Condition="Exists('$(MSBuildThisFileDirectory)..\.config\dotnet-tools.json') and '$(MapsterSetupExitCode)' != '' and '$(MapsterSetupExitCode)' != '0'" />
  </Target>

  <!-- Run Mapster only when project targets net9.0 (either current TFM or TargetFrameworks contains net9.0). -->
  <Target Name="Mapster" AfterTargets="AfterBuild"
          Condition="'$(MapsterEnabled)' == 'true' and ( '$(TargetFramework)' == 'net9.0' or $([System.String]::Copy('$(TargetFrameworks)').Contains('net9.0')) == 'True' )" >

    <Message Importance="high" Text="Mapster: starting code generation for $(MSBuildProjectName)..." />

    <!-- Generate into a non-runtime-specific obj/mapster folder to allow reuse across TFMs -->
    <Exec WorkingDirectory="$(MSBuildProjectDirectory)"
          Command="dotnet mapster model -a &quot;$(TargetPath)&quot; -o &quot;$(BaseIntermediateOutputPath)mapster&quot; -r -N"
          ContinueOnError="false" />

    <Exec WorkingDirectory="$(MSBuildProjectDirectory)"
          Command="dotnet mapster extension -a &quot;$(TargetPath)&quot; -o &quot;$(BaseIntermediateOutputPath)mapster&quot; -N"
          ContinueOnError="false" />

    <Exec WorkingDirectory="$(MSBuildProjectDirectory)"
          Command="dotnet mapster mapper -a &quot;$(TargetPath)&quot; -o &quot;$(BaseIntermediateOutputPath)mapster&quot; -N"
          ContinueOnError="false" />
    
    <Message Importance="high" Text="Mapster: finished generation for $(MSBuildProjectName)." />
  </Target>
  <ItemGroup>
    <GeneratedMappings Include="**\\mapster\\*.g.cs" />
  </ItemGroup>

  <Target Name="CleanGenerated" BeforeTargets="Clean">
    <Message Importance="low" Text="CleanGenerated: removing mapster generated files..." Condition="Exists('$(BaseIntermediateOutputPath)mapster')" />
    <Delete Files="@(GeneratedMappings)" ContinueOnError="false" Condition="Exists('$(BaseIntermediateOutputPath)mapster')" />
  </Target>
</Project>

the Project file .csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <RootNamespace>DevTKSS.MyProject.DataContracts</RootNamespace>
    <AssemblyName>DevTKSS.MyProject.DataContracts</AssemblyName>
    <!-- The Dependending Projects are already migrated to .net10.0 so the net9.0 is only to enable dotnet-mapster -->
    <TargetFrameworks>net9.0;net10.0</TargetFrameworks>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <MapsterEnabled>true</MapsterEnabled>
    <MapsterPath>$(ProjectDir)**\mapster\**\*.g.cs</MapsterPath>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Mapster" />
    <PackageReference Include="Mapster.DependencyInjection" />
    <PackageReference Include="Mapster.Async" />
    <PackageReference Include="Mapster.Immutable" />
    <PackageReference Include="Mapster.EFCore" />
  </ItemGroup>

  <!-- Mapster generated files: expose as visible None items and set DependentUpon to the source file when possible -->
  <ItemGroup Label="Include Mapster Generated Files" Condition="'$(MapsterEnabled)' == 'true' and Exists('$(BaseIntermediateOutputPath)mapster')">
    <Compile Remove="$(MapsterPath)" />
    <None Include="$(MapsterPath)">
      <Link>mapster-generated/$(RecursiveDir)%(Filename)%(Extension)</Link>
      <Visible>true</Visible>
    </None>
  </ItemGroup>
</Project>

By the way, refering to your Mapster.Tool Wiki Page this -r should generate Record types but you are not mentioning that only the dotnet-mapster model command actually supports it reading the Options in the src! Maybe this should be told and not generalized listed for all of the commands.

image

The actual src/Mapster.Tool/MapperOptions.cs and ExtensionOptions.csdoesn't contain this Option either and resulting from that, its unknown to the compiled dotnet tool we are getting and produces this Error:

Mapster.Tool 9.0.0-pre01+998402908cdc59d2bbdbab5fbc1d5062153494e8
1>  Copyright (c) 2025 Chaowlert Chaisrichalermpol, Eric Swann, Andreas Ravnestad
1>
1>  ERROR(S):
1>    Option 'r' is unknown.
1>  USAGE:
1>  Generate extensions:
1>    dotnet mapster extension mapper --assembly /Path/To/YourAssembly.dll --output
1>    Models
1>
1>    -a, --assembly             Required. Assembly to scan
1>
1>    -o, --output               (Default: Models) Output directory.
1>
1>    -n, --namespace            Namespace for extensions
1>
1>    -p, --printFullTypeName    Set true to print full type name
1>
1>    -b, --baseNamespace        Provide base namespace to generate nested output &
1>                               namespace
1>
1>    -s, --skipExisting         Set true to skip generating already existing files
1>
1>    -N, --nullableDirective    Set true to add "#nullable enable" to the top of
1>                               generated extension files
1>
1>    --help                     Display this help screen.
1>
1>    --version                  Display version information.

but I am not sure from the Attribute docs of mapster, if there might be one of the arguments that I am missing but cases like this:
image

are generating this:
image

while expected would be the summary to actually optional (missing = null or = "") and the TemperatureF ... not sure is this a case for your IgnoreAttribute? but then I would also not get this to be readable. I dont see a way to exclude some from the ctor but still include them as { get; } while it should be keeping the code that is setting the property🤷
This here would be a possible expectation:

/// <summary>
/// A Weather Forecast for a specific date
/// </summary>
/// <param name="Date">Gets the Date of the Forecast.</param>
/// <param name="TemperatureC">Gets the Forecast Temperature in Celsius.</param>
/// <param name="Summary">Get a description of how the weather will feel.</param>
public record WeatherForecastQuery(DateOnly Date, double TemperatureC, string? Summary = null)
{
    /// <summary>
    /// Gets the Forecast Temperature in Fahrenheit
    /// </summary>
    public double TemperatureF => 32 + (TemperatureC * 9 / 5);
}

Maybe you could check on this and add it to any kind of back log?

@DocSvartz
Copy link
Author

I'm very glad that you managed to solve this 🤩
Don't be shy about opening an issue on topics that interest you.

If i understand correctly, it is Business logic:

public double TemperatureF => 32 + (TemperatureC * 9 / 5);

Dtos shouldn't contain Business logic, but simply serve to transfer data.

I dont see a way to exclude some from the ctor but still include them as { get; } while it should be keeping the code that is setting the property🤷

Yes, there is a problem with that.

Also keep in mind that the record types in the Mapster Wiki are not actually equal Records in C# .

Records mapping has already been added in Mapster, but there is no generation with MapsterTool yet.

@DevTKSS
Copy link
Collaborator

DevTKSS commented Nov 28, 2025

@DocSvartz 🤔😅 assumed they are the same!
Will look again into this.
Can you tell how someone could contribute to such wiki ? I always used to contribute to md files produced by docfx for example also set one up for my own samples repo🤔
I just seen your much issues load and thought you would just only want to stay where you are and keep it stable as possible but not proceeding, which would be quite sad because I would see your NuGet as great and most maintained alternative to AutoMapper which seems to require payment and I prefer staying on OSS or similar projects and if I see problems with something I tend to checkig if I can help with it and (if yes) contribute with a PR because I know that beyond every good Dev potentially is also 👀 (hope so at least 😜) a life or/and a family to care for beside creating great stuff 😁

@DevTKSS
Copy link
Collaborator

DevTKSS commented Nov 28, 2025

@DocSvartz and one question to the PR here:
What is the reason for your don't want to upgrade or add the new tfm's? Is it just for the review time you maybe not have, or what is blocking you from sending even the net9 into stable version release?
Reasons I could imagine...

  • specific issues
  • test coverage
  • ?

@DocSvartz
Copy link
Author

@DevTKSS
about Wiki - I haven't edited the wiki yet either, so I can't offer any advice. 😔

I and @stagep recently joined the Mapster.
I am adding new features from issue or fix bugs, but i am not by publishing new versions.

See this discussion and contact @andrerav if you want to become one of maintainers Mapster.

In fact, quite a lot of changes have accumulated since version 7.4.0, There was one big problem and a lot of changes associated with it :).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants