dotnet / dotnet/project-system
Prevent assembly-loading for inserted launch profile
- Dominant language
- C#
- Stars
- 1k
- Forks
- 415
- PR merge metrics
- No merged PRs in 30d
Description
Our extension makes use of the feature of non-persisted launch profiles so that we can automatically insert our custom profile for all ASP.NET Core projects. The current approach requires imperative code to be executed that explicitly calls ILaunchSettingsProvider to get the profile inserted. But this obviously requires our assembly to be loaded in order to execute this code. We'd like there to be a way for our custom launch profile to be selectable without our assembly being loaded and only be loaded when the user selects our profile.
The proposal would be to make use of MEF metadata that describes the launch profile sufficiently for the project system to display that profile.
Here's a proposed design:
```
[Export(typeof(INonPersistedLaunchProfileProvider)]
[ExportMetadata("DefaultLaunchProfileName", "My Launch Profile")]
[ExportMetadata("LaunchProfileCommandName", "MyLaunchProfile")]
public class MyLaunchProfileProvider : INonPersistedLaunchProfileProvider
{
ILaunchProfile INonPersistedLaunchProfileProvider.CreateLaunchProfile() { … }
void OnSelectingLaunchProfile(ILaunchProfile launchProfile) { … }
}
````
Then the project system code would import all INonPersistedLaunchProfileProvider components, but do so lazily, and use the metadata of those components for populating the list of selectable launch profiles. Then when that profile is being selected, either in the toolbar or in the project’s Debug tab, you would access the lazily loaded instance and invoke its CreateLaunchProfile method to get the fully populated state of the profile. This fulfills the requirement of not loading our assembly until the user selects the launch profile that we’re providing. The OnSelectingLaunchProfile method would then be called so we can take the appropriate action.
In addition, let’s consider the scenario where the user has selected our profile, saved their project state, and then closed and reopened that project. Upon opening the project, our profile is selected so we need our assembly to be loaded. The MEF component metadata for LaunchProfileCommandName would be used by the project system to recognize this. It would see that the currently selected profile has a command name that matches the metadata that we’ve exported. This matching would need to be done by command name rather than profile name since the user is free to change their profile’s name or even have multiple profiles that are all making use of the same command name. So at this point you’d access the lazily loaded instance of our provider and call the OnSelectingLaunchProfile method to let us know.
For our particular requirements, we would not want to have an additional non-persisted launch profile show up if the user already had a persisted one with the same command name. Other extensions that make use of this API may want different behavior perhaps, so you may want to consider having some sort of mode metadata available to control that behavior.
For reference, our implementation of the OnSelectingLaunchProfile would likely setup a SourceBlock link on ILaunchSettingsProvider so that we can be notified when the active profile has been set to our profile. When it is, then we’ll add a project capability that will light up the rest of our MEF components that apply to this launch profile.
Contributor guide
Assessment
This issue has not been assessed yet.