For types that have a `CancellationTokenSource` that is triggered during `Dispose()`, we should check to see if it has already been cancelled to avoid disposing twice. Implicitly, there's a race here if there are multiple threads calling `DIspose()`, but these are all handled by the DI containers we use.
`RazorProjectService` doesn't need to force itself to be initialized when the language server is initialized. It's registered as an `IRazorStartupService`, so it starts initializing right away. Since all `RazorProjectService` public entry points await initialization, we don't need to force it to finish initializing in `OnInitialized`. This is especially true if the driver itself implicitly waits for `OnInitialized`.
As part of this change, I've made `RazorProjectService` own the misc files project, rather than `SnapshotResolver`, which fixes a potential issue with initialization order.
Since the lifetime of the `RazorProjectInfoDriver` is the same as the language service, we let our language server client create and initialize it during activation. This means that the driver no longer needs to check if `IsLSPEditorAvailable()` since its constructed by the LSP editor's language client.
Microsoft.SourceBuild.Intermediate.source-build-reference-packages
From Version 9.0.0-alpha.1.24278.2 -> To Version 9.0.0-alpha.1.24304.1
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
`ISnapshotResolver` is really just a collection of methods that operate
on `IProjectSnapshotManager`. Given that, its existence has also seemed
a bit contrived. Even stranger, `ISnapshotResolver` is responsible the
miscellaneous files project in the language server.
This change ensures that the miscellaneous files project is added to the
`IProejctSnapshotManager` when the project manager is created. Then, it
transforms all of the `ISnapshotResolver` methods into extension methods
on `IProjectSnapshotManager`.