Closed jorisdebock closed 4 years ago
Hi, This is a problem with SmartCodeGenerator rather than MappingGenerator plugin. Please take a look at https://github.com/cezarypiatek/SmartCodeGenerator/issues/1 Unfortunately, at the moment there is no solution for that. I'm waiting for a help from guys who work on https://github.com/daveaglick/Buildalyzer
Duplicates #104
@cezarypiatek but this is not a project reference problem, there are no project references in this example that are used in the generation part.
I have been playing around a bit and I see two things go wrong.
when I modify the engine target conditions to
<Target Name="GenerateFilesWithSmartCodeGenerator" AfterTargets="ProtoCompile" BeforeTargets="CoreCompile" Condition="'$(SmartGeneratorProcessing)' != 'true'">
it will run after the grpc/proto compilation step
I am not sure how the roslyn workspace etc work in regard to the /obj folder files. Is this also caused by the issues you mentioned or should I open an issue for this on the smartcodegenerator repository?
Thanks for the due diligence investigation. I need to verify how roslyn workspace is created and updated with generated code.
Can you try to put proto contracts in a separate project and add it as a reference to the project where you are using MappingGenerator?
I have put the proto contracts in a separate netcoreapp3.1 project
But the result is the same the generated code still only resides in the /obj folder of the separate project. tested with and without the modification of the msbuild step order
var methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodDeclaration);
ReturnType.Kind: ErrorType
In branch: seperate-project-for-protos (this branch is without the msbuild step modification) https://github.com/wazowsk1/GrpcService1/tree/seperate-project-for-protos
I have found the following post on stackoverflow https://stackoverflow.com/questions/42738463/how-to-find-the-obj-directory-for-c-sharp-projects-using-roslyn-msbuildworkspa which pointed me to the following direction.
The /obj intermediate files are not loaded into the project when calling OpenProject on the workspace and there seems to be no option to load these.
So in the Engine, I have added the files manually to the project with the following code.
var files = Directory.GetFiles(options.OutputPath, "*.cs");
MSBuildLocator.RegisterInstance(selectedMsBuildInstance);
using (var workspace = MsBuildHelper.CreateMsBuildWorkspace(progressReporter))
{
var project = await workspace.OpenProjectAsync(options.ProjectPath, progressReporter);
foreach (var file in files)
{
var textDocument = project.AddDocument(file, File.ReadAllText(file), filePath: file);
project = textDocument.Project;
}
var generatorAssemblySearchPaths = options.GetGeneratorPluginsSearchPaths(progressReporter);
var generator = new CompilationGenerator(generatorAssemblySearchPaths, options.OutputPath, progressReporter);
await generator.Process(project);
}
The results are that the type is now known to roslyn and the mapping generator is working as expected. (tested with 1 project including the proto files)
public virtual HelloReply MapHello(Hello hello)
{
return new HelloReply()
{
Message = hello.Message
};
}
@cezarypiatek what do you think of this possible solution?
Those files that you are loading manually probably comes from the previous compilation so this won't work after build
clean. The presents of the file in the obj
directory doesn't mean that it should be included in the compilation, dynamically generated files should be additionally added to the Compile
collection of the MSBuild.
It should work even after a clean, since the generated files are generated before the smartcodegenerator target.
The generated files are indeed added to the Compile collection of msbuild, but this collection is not known to MSBuildWorkspace. Instead of doing a GetFiles() passing the Compile collection to the smartcodegenerator is also possible.
Sorry for long response time and no specific action so far but right now I'm in the middle of moving into the new apartment and it will take the next two weeks.
Back to the problem, I will try to verify once again why those files are not included in the compilation and if there is no option for that in MsBuildWorkspace then I will expose some option to enable including additional files.
no problem, look at it when you have time.
In my fork of the SmartCodeEngine you can see my modifications which are so far working for me. I am not sure if this is the best solution, but the only one I found so far. It's not yet tested with multiple projects where the proto contracts are in another project than the mapping code. https://github.com/wazowsk1/SmartCodeGenerator/tree/add-msbuild-compile-paths-to-msbuildworkspace-documents
A new version of SmartCodeGenerator.Engine
has been released. Please update the package and verify if it works correctly.
public virtual HelloReply MapHello(Hello hello)
{
return new HelloReply()
{
Message = hello.Message
};
}
yes works :)
When using the GrpcService project, the mappings are not generated on build. When using the extension it works as expected
I think this is because the Grpc objects are also generated.
The targetType is marked as ErrorType Kind = ErrorType
Example repository https://github.com/wazowsk1/GrpcService1/blob/master/GrpcService1/Services/GreeterService.cs