fiseni / SmartAnnotations

A library for .NET that uses source generators to automatically generate data annotations for your models.
MIT License
50 stars 5 forks source link

Running the compilation and loading the referenced assemblies. #1

Open fiseni opened 3 years ago

fiseni commented 3 years ago

In this project, we have a bit more complex scenario. We're not generating some simple "static" content. Just looking at the source code is not enough for us. We have to run portions of the code, make some decisions and then generate appropriate content. And that's an issue if you're using Visual Studio and you're consuming the library from .NET 5 project.

The general workflow is the following:

This would work in any environment, no problem here. But, in our case, during step 3, we do actually emit the compilation and load the temporary assembly so we can execute the fluent configurations. And that's where the issue is.

If you're doing dotnet build then it's all fine. But, if you're building it through VS, everything is being executed in VS runtime context. If you do AppDomain.CurrentDomain.GetAssemblies() you'll notice that the runtime is .NET Framework (not a surprise), or if you check GetCurrentDirectory() you'll see a VS app path (\Program Files...). So, in this case, executing the temp assembly will fail, since will fail to load NET5 runtime. It gets even more complicated if there is a need to load referenced assemblies. I tried all kinds of stuff, even considered manually parsing the syntax tree (that's just an insane idea, btw).

There is an active issue on Roslyn here https://github.com/dotnet/roslyn/issues/45060. Entity Framework team also has a similar scenario, and they need to run some code.

For now, this is my TypeResolver implementation. I'd love it if anyone has a better solution to this, and any contribution is welcome. I'm far from an expert in this area, and I'm open to any suggestions.

GianvitoDifilippo commented 2 years ago

Hi! Any news on this matter? Do you think the same problem will arise if I try to emit IL code inside my generator using System.Reflection.Emit?

fiseni commented 2 years ago

I don't see any solution to this. To be honest, this is a sinful project 😄 we're messing up with tooling and user runtime, and that's not a smart idea. It was an experimental project, and it will remain as beta until the whole workflow of source generators is changed.