Mapster icon indicating copy to clipboard operation
Mapster copied to clipboard

Why not .net build-in code generator?

Open GihanSoft opened this issue 3 years ago • 3 comments

This wonderful package use a cli tool for code generation. but why not using build-in .net code gen? It won't add files in project and doing it auto in build process.

GihanSoft avatar Jun 29 '22 10:06 GihanSoft

I think in the case of the mapper, the user should be able to save the generated models in source control. And dotnet generator has a problem with that. You can specify <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> and <CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath> but this will emit output from any generators not just from the Mapster. Not sure if this has been resolved.

devbased avatar Jun 30 '22 17:06 devbased

@devbased not actually. Auto-gen files are step-able and visible. The only reason can be customizing Auto-gen code and I thing it's not good thing to do.

GihanSoft avatar Jul 02 '22 10:07 GihanSoft

@devbased , the rule of thumb is to NOT commit generated files to SCM. For those who also can't see generated files being committed to git , here is the workaround :

<Target Name="Mapster" BeforeTargets="BeforeBuild;BeforeRebuild" Condition="'$(EnableMapsterCodeGen)' == 'true' And '$(ONCE)' != 'TRUE'">
        <PropertyGroup>
            <MapsterGeneratedFiles>$(MapsterCodeGenDirectory)\*.g.cs</MapsterGeneratedFiles>
        </PropertyGroup>
        <ItemGroup>
            <Compile Remove="$(MapsterGeneratedFiles)" />
        </ItemGroup>
        <RemoveDir Directories="$(MapsterCodeGenDirectory)"/>
        <Exec Command="dotnet msbuild $(ProjectPath) -p:Configuration=$(Configuration)"
              EnvironmentVariables="ONCE=TRUE" />
        <Exec Command="dotnet tool update Mapster.Tool --global --version=8.3.0" />
        <Exec WorkingDirectory="$(ProjectDir)"
              Command="dotnet mapster mapper -o $(MapsterCodeGenDirectory) -a $(TargetDir)$(ProjectName).dll " />
        <ItemGroup>
            <Compile Include="$(MapsterGeneratedFiles)" />
        </ItemGroup>
    </Target>

This target removes the generated files and spawns another dotnet msbuild command to regenerate mappings during normal build. If you adopt this approach, DO NOT reference generated classes from your code base, use only interfaces and have DI to discover classes that implements interface that is annotated with [Mapper] attribute :

Pseudo-Code:


allAsseblies.AllTypes.Select(type =>{
var i = type.Interfaces.FirstOrDefault(i->i.HasAttribute<MapperAttribute>());
return null==i ? null : new (i,type)
})
.WhereNotNull()
.ForEach(pair=>container.Register(pair.type).As(pair.i)

Usage :

<PropertyGroup>
    <EnableMapsterCodeGen>true</EnableMapsterCodeGen>
    <MapsterCodeGenDirectory>GeneratedMappings</MapsterCodeGenDirectory>
  </PropertyGroup>

jvmlet avatar Jan 23 '23 10:01 jvmlet