Closed ScottKane closed 2 years ago
To follow proper DDD given only 2 projects for brevity, a lot of the output source should not be available to Domain, but should be available to Application.
Why is Domain
asking for code to be generated in it then? Why not only have Application
run the generator? I'm not really understanding why things are configured in this fashion.
--
For context, we just do what you tell us to do. If you have a generator in Domain
and it generates code, then teh code will be generated in Domain
. Likewise, if you don't have a generator in Application
, then you won't get generated code in it. So it sounds like we're doing exactly what you set things up to do.
It's done in this way so that domain entities can be marked as features which will generate all the CRUD required for the feature. Even if the model defining the feature was done in Application
, I would have the same problem in code that needs to be elsewhere (there's more projects than Domain
/Application
) I only mention 2 to get the point across.
Having to create a type in each project for each part of a feature needed wouldn't save much time vs just writing all the CRUD operations manually whereas just marking an entity as a feature and having everything spit out in the right place would save a lot.
This is not really a bug, more of an enhancement to source generators. Having some persisted state or even the option of persisting the syntax receiver between invocations would be nice. That way, other projects can get their generated code without having to mark a type with an attribute per project to get them.
It's done in this way so that domain entities can be marked as features which will generate all the CRUD required for the feature.
if all the CRUD is required for the feature, then what is the issue here? :)
--
Put another way, if you were writing the code out manually please show us how it would look in each project. Thanks!
Small repo giving an example of how the CRUD features would be set out manually showing what classes could be available in each project: https://github.com/ScottKane/SourceGenerators
What should I be looking at in there? Which are the files showing what would be generated manually? Thanks!
That is how the class structure would look if they were to be manually created, what I would like to do is just have a Feature
attribute to generate all of that for me.
In the sample the example entity is Domain/Entities/Product
.
There would then be commands and queries for the CRUD functionality in Application
(AddEditProductCommand, DeleteProductCommand, GetAllProductsQuery, GetProductByIdQuery each with their respective handlers to do work in the DB). Application/Features/Product
Then there would be a mapping profile which maps the commands/queries to the domain entity. Application/Mappings/ProductProfile
There would then be a repository for the product (repository pattern used optionally if not using EF core) Infrastructure/Repositories
Then there would be a controller presenting the endpoints for products Server/Controllers
As you can see there are a lot of classes that I am wanting to generate just from the entity in Domain
and they are in various projects.
The classes are lacking an actual body as I don't want to build a working api sample with EF core, MediatR etc but it gives you an idea of the layout of the classes I'm trying to generate.
@ScottKane would you be willing to come to discord to discuss this more? I'm not really understanding waht you're asking for here, and it might be easier to just hash it out with a real-time chat. Thanks!
Sure no problem
ok. discord.gg/csharp. You can DM me using 'metasyntactic'. Thanks! :)
@CyrusNajmabadi I DM'd you on discord
Closing out as working as intended. The right approach is to just example ISymbols in downstream compilations. It is very much by-design that when compiling one compilation there is zero knowledge that any symbols being references even came from C# (and thus could even have their trees be examined). We very much want to keep the separation here and only have 'syntax' be a thing that one has access to from within the compilation being compiled.
With the current implementation of source generators, there is no way for generated code to respect a domain driven design.
For example, I have the following projects, both referencing the generator project:
Domain
andApplication
Domain contains a model with the
Feature
attribute (causes CRUD source to be generated for the given feature):To follow proper DDD given only 2 projects for brevity, a lot of the output source should not be available to
Domain
, but should be available toApplication
.Because the generator will run for each project,
Domain
will get all of the source because it uses theFeature
attribute butApplication
will get nothing.I think there needs to be some way to have a persisted syntax receiver which would allow the correct projects to get the desired source.
If there's another way to do this I've not found it, because as it stands, you can't even just serialize the state into the generator output directory because one run gets
AppData\Local\Temp\VBCSCompiler\AnalyzerAssemblyLoader\92fd63172da84323a0ba94e97aa9857a\6
and the other getsGenerators\bin\Debug\netstandard2.0
I get that I could just let the types be in
Domain
and they would filter through by referencing but they should really be generated intoApplication