-
Notifications
You must be signed in to change notification settings - Fork 34
Feature Service API
Feature Service is an API that offers a standardized way to disable various Visual Studio features.
Possible uses are:
- Inline rename to disable interactive popups
- Multi caret to disable completion
- R# to disable completion in C# documents
Previously, Visual Studio features were disabled through a combination of method calls that ultimately suppress the feature from being visible, but they cause side effects, a growing need to maintain these hacks on our side and various other developer frustrations.
The API is defined in Microsoft.VisualStudio.Utilities
FeatureDefinition is a MEF part that registers a feature, later accessed by string. Applicable metadata:
- Required
Name(string), used to disable the feature or check its status - Optional
BaseDefinition(string), which means that feature is disabled if its base feature is disabled
We provide a few feature names in Microsoft.VisualStudio.Utilities.PredefinedEditorFeatureNames:
Editor, Popup, InteractivePopup and Completion. This list will grow as we onboard more features.
IFeatureServiceFactory is a MEF part used to obtain instances of IFeatureService
-
GlobalFeatureServicereturns VS-wideIFeatureService -
GetOrCreate(IPropertyOwner scope)returnsIFeatureServiceapplicable to given scope, for exampleITextView
IFeatureController is an empty interface used to uniquely identifies someone who attempts to disable a feature.
- It prevents unintentional double-disables or double-enables.
- We use it also collect telemetry on who disables features we build 💔
IFeatureService is used to disable\restore a feature and to check its availability.
-
The service tracks disabled features in its scope, unless this is a
IFeatureServiceFactory.GlobalFeatureService -
IsEnabled(string featureName)returns whether a feature or its base is disabled in this scope or parent scope. -
Disable(string featureName, IFeatureController controller)disables a feature
[Export]
[Name(nameof(MyFeature))] // required
[BaseDefinition(PredefinedEditorFeatureNames.Popup)] // zero or more BaseDefinitions are allowed
public FeatureDefinition MyFeature;
[Import]
IFeatureServiceFactory FeatureServiceFactory;
IFeatureService globalService = FeatureServiceFactory.GlobalFeatureService;
IFeatureService localService = FeatureServiceFactory.GetOrCreate(scope); // scope is an IPropertyOwner
// Also have a reference to <see cref="IFeatureController"/>:
IFeatureController MyFeatureController;
// Interact with the <see cref="IFeatureService"/>:
globalService.Disable(PredefinedEditorFeatureNames.Popup, MyFeatureController);
localService.IsEnabled(PredefinedEditorFeatureNames.Completion); // returns false, because Popup is a base definition of Completion and because global scope is a superset of local scope.