예제 #1
0
        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 !;
예제 #2
0
        /// <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);
            }
        }