private bool TryGetProviderContext <T>(IVsReferenceManagerUser manager, out T context) where T : IVsReferenceProviderContext { ThreadHelper.ThrowIfNotOnUIThread(); T?value = manager.GetProviderContexts().OfType <T>().FirstOrDefault(); if (value is not null) { context = value; return(true); } context = default !;
/// <summary> /// Removes the given references from the project. /// </summary> /// <param name="references">The references to remove.</param> /// <returns>A task.</returns> public async Task RemoveAsync(params Reference[] references) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); // There doesn't seem to be an easy way to actually remove references from a project. // There is no direct way to map an `IVsReference` instance to the provider that handles // that type of reference, and the `IVsReferenceProviderContext` has no way to remove a // reference from its `References` property. What we do here might seem like a bit of a hack, // but it appears to work fine. // // We start by creating a mapping from an `IVsReference` type to the corresponding provider // context by getting each provider context to create a reference object. The provider // context just creates a new object and doesn't seem to do anything with it, so this // shouldn't have any side effects. This gives us a way to get the provider context // that an `IVsReference` object is handled by. // // But, the provider contexts from the manager contain all of the existing references with no // way to remove reference objects from them, so we can't pass those contexts to the manager // when calling `ChangeReferences()` because that will remove all existing references! // What we will do is create an instance of our own implementation of a provider context // so that the provider context will only contain the references that we want to remove. Dictionary <Type, RemovingReferenceProviderContext> contextsByReferenceType = new(); IVsReferenceManagerUser manager = GetManager(); foreach (IVsReferenceProviderContext context in manager.GetProviderContexts().OfType <IVsReferenceProviderContext>()) { contextsByReferenceType[context.CreateReference().GetType()] = new RemovingReferenceProviderContext(context.ProviderGuid); } foreach (Reference reference in references) { if (contextsByReferenceType.TryGetValue(reference.VsReference.GetType(), out RemovingReferenceProviderContext context)) { context.AddReference(reference.VsReference); } } foreach (IVsReferenceProviderContext context in contextsByReferenceType.Values.Where((x) => x.HasReferences)) { manager.ChangeReferences((uint)__VSREFERENCECHANGEOPERATION.VSREFERENCECHANGEOPERATION_REMOVE, context); } }