-
Notifications
You must be signed in to change notification settings - Fork 476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve usage of ProjectReferences in the AppHost #1074
Comments
We should be able to control these transitive dependency behaviors via In order to guard against an unforeseen future scenario where a user does want a ProjectReference with full transitive dependency behavior in their AppHost project, we could update our scaffolding to append a custom metadata value to the service ProjectReference items. Something along the lines of |
@baronfel thoughts? |
When I tried that it broke our current code-generation logic. Likely it can be fixed though by altering our approach. |
Oh boy, do I! I did a lot of this in this commit of a branch with the goal of keeping ProjectReferences for describing the relationship between components. It works quite well! You can go even further by removing the requirement to even build. The ProjectReference metadata changes that @danegsta mentions could be handled by the Aspire.Hosting.Targets themselves if you have the custom metadata hook he's describing - in this case you could have an <ItemGroup>
<ProjectReference Update="@(ProjectReference)" Condition="'%(ProjectReference.IsAspireService)' == 'true'">
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<ProjectReference>
</ItemGroup> That's an established and fine pattern - the only potential concern could be if a referenced project exposes multiple TFMs. The branch I have above kind of works like that, but can't really be used in the aspire samples themselves because they take a project reference on aspire itself, instead of a PackageReference. That gap would be solved if you were ok with needing to add a piece of metadata. If you wanted to go further then you could have the Aspire Host not even build the projects by setting |
Yes, you get around this by changing the code-generation logic to operate on the ProjectReferences themselves, which you can see in this diff. You ask each project reference to compute its output path (a very fast operation) and then go from there. |
I'm surprised to see an explicit |
Do you mean on my branch @rainersigwald? That could work if the other projects were built normally first, which currently is the case, but that's not strictly required just to generate the codegen'd structures. |
A problem with blindly setting A thought I've been throwing around is to create a new type of |
I don't mind that suggestion @eerhardt but I think it's worth pointing it means we lose a built-in CLI story for adding references to the AppHost as one can't just use |
@eerhardt yeah, that would really just come down to whether we use |
If that's a high priority the inverse of |
Wasn't trying to convey a priority, just wanted to ensure it was entered into the conversation as we figure this out. |
@rainersigwald only downside with the inverse property is that we could break existing projects (the Aspire tests, for example, would probably be broken without adding |
The inverse property idea seems like a bad precedent to set, i.e. making regular looking |
|
😬 |
Regardless of the approach, we should make sure to add a comment to the AppHost project template(s) to explain the behavior for anyone looking to manually add a service project reference. |
Extending |
At a high-level there are 2 problems with how we are using ProjectReference to reference the individual "service application" projects in the AppHost. 1. The AppHost may not have a compatible TFM with the referenced application project. For example if the referenced application project was targeting `net8-windows`. 2. When we are generating IServiceMetadata code, we are using ReferencePathWithRefAssemblies items, which means if the ProjectReference has ReferenceOutputAssembly="false" on it, no IServiceMetadata code will be generated. To resolve these issues, we are taking the following approach: - By default ProjectReferences in the AppHost will mean a reference to a "service application", and not a regular project reference. If an AppHost project truly wants a ProjectReference to another project, it can be marked as `<ProjectReference Include="..." AppHostLibrary="true" />`. - ProjectReferences to service applications will be marked `ReferenceOutputAssembly=false`, `SkipGetTargetFrameworkProperties=true`, `ExcludeAssets=all`. This will cause the AppHost to not reference the service app projects. - Refactor the IServiceMetadata code gen to act directly on ProjectReference items. Fix dotnet#1074 Fix dotnet#1563
At a high-level there are 2 problems with how we are using ProjectReference to reference the individual "service application" projects in the AppHost. 1. The AppHost may not have a compatible TFM with the referenced application project. For example if the referenced application project was targeting `net8-windows`. 2. When we are generating IServiceMetadata code, we are using ReferencePathWithRefAssemblies items, which means if the ProjectReference has ReferenceOutputAssembly="false" on it, no IServiceMetadata code will be generated. To resolve these issues, we are taking the following approach: - By default ProjectReferences in the AppHost will mean a reference to a "service application", and not a regular project reference. If an AppHost project truly wants a ProjectReference to another project, it can be marked as `<ProjectReference Include="..." AppHostLibrary="true" />`. - ProjectReferences to service applications will be marked `ReferenceOutputAssembly=false`, `SkipGetTargetFrameworkProperties=true`, `ExcludeAssets=all`. This will cause the AppHost to not reference the service app projects. - Refactor the IServiceMetadata code gen to act directly on ProjectReference items. Fix dotnet#1074 Fix dotnet#1563
At a high-level there are 2 problems with how we are using ProjectReference to reference the individual "service application" projects in the AppHost. 1. The AppHost may not have a compatible TFM with the referenced application project. For example if the referenced application project was targeting `net8-windows`. 2. When we are generating IServiceMetadata code, we are using ReferencePathWithRefAssemblies items, which means if the ProjectReference has ReferenceOutputAssembly="false" on it, no IServiceMetadata code will be generated. To resolve these issues, we are taking the following approach: - By default ProjectReferences in the AppHost will mean a reference to a "service application", and not a regular project reference. If an AppHost project truly wants a ProjectReference to another project, it can be marked as `<ProjectReference Include="..." AppHostLibrary="true" />`. - ProjectReferences to service applications will be marked `ReferenceOutputAssembly=false`, `SkipGetTargetFrameworkProperties=true`, `ExcludeAssets=all`. This will cause the AppHost to not reference the service app projects. - Refactor the IServiceMetadata code gen to act directly on ProjectReference items. Fix dotnet#1074 Fix dotnet#1563
* Refactor ProjectReferences in AppHost At a high-level there are 2 problems with how we are using ProjectReference to reference the individual "service application" projects in the AppHost. 1. The AppHost may not have a compatible TFM with the referenced application project. For example if the referenced application project was targeting `net8-windows`. 2. When we are generating IServiceMetadata code, we are using ReferencePathWithRefAssemblies items, which means if the ProjectReference has ReferenceOutputAssembly="false" on it, no IServiceMetadata code will be generated. To resolve these issues, we are taking the following approach: - By default ProjectReferences in the AppHost will mean a reference to a "project resource", and not a regular project reference. If an AppHost project truly wants a ProjectReference to another project, it can be marked as `<ProjectReference Include="..." IsAspireProjectResource="false" />`. - ProjectReferences to project resources will be marked `ReferenceOutputAssembly=false`, `SkipGetTargetFrameworkProperties=true`, `ExcludeAssets=all`. This will cause the AppHost to not reference the app projects. - Refactor the IServiceMetadata code gen to act directly on ProjectReference items. Fix #1074 Fix #1563 Fix #1278 * Move ProjectReference defaulting logic into the SDK targets so it is respected by NuGet Restore * Add a build warning informing developers when they ProjectReference a library in the AppHost, but didn't set IsAspireProjectResource=false. * Add test to ensure warning is emitted. * Rename ProjectReference properties - IsAspireProjectResource=false - Setting this to false opts you into being an "AppHost library", you don't get "Projects" code generated, and you start referencing the project - ServiceNameOverride => AspireProjectMetadataTypeName This also allows us to rename IServiceMetadata to IProjectMetadata.
We use project references from the app host to service projects for 2 reasons:
dotnet run
just works. We get an orchestrated build and run experience for free from the command line.There are 2 major things that have come up recently with respect to the app host and orchestration:
The text was updated successfully, but these errors were encountered: