Skip to content

Commit 1bf8b96

Browse files
authored
Merge pull request #6 from maiak/dev/mapropse/inside_the_sdk
Update to Inside the Sdk topics
2 parents ff3c40c + 3441298 commit 1bf8b96

File tree

5 files changed

+64
-72
lines changed

5 files changed

+64
-72
lines changed

docs/extensibility/visualstudio.extensibility/inside-the-sdk/activation-constraints.md

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ Multiple activation constraints can be combined together using the [`And`](/dotn
2525
In the following example, the command configuration property `EnabledWhen` defines when the command is in the enabled state. The `ClientContext` method is one of the activation constraint factory methods. It generates the activation constraint, given the two arguments, a string and regular expression pattern to match against that string. Therefore, the following code indicates that a command is enabled when the user has selected a file with one of those extensions.
2626

2727
```csharp
28-
public override CommandConfiguration CommandConfiguration => new("My command")
28+
public override CommandConfiguration CommandConfiguration => new("%My command.DisplayName%")
2929
{
3030
EnabledWhen = ActivationConstraint.ClientContext(ClientContextKey.Shell.ActiveSelectionFileName, @"\.(jpg|jpeg|txt)$"),
3131
};
3232
```
3333

34-
The `ClientContextKey` class provides the range of IDE state information that you can test against; for a table of values, see [Client context keys](#client-context-keys).
34+
The [`ClientContextKey`](/dotnet/api/microsoft.visualstudio.extensibility.clientcontextkey) class provides the range of IDE state information that you can test against; for a table of values, see [Client context keys](#client-context-keys).
3535

3636
The following example shows how to combine multiple constraints:
3737

@@ -51,67 +51,46 @@ EnabledWhen =
5151

5252
## Activation constraint properties
5353

54-
Currently, what you can control with activation constraints is the loading of an extension, and the enabled or visible state of a command. The configuration types contain property of type `ActivationConstraint`, typically with a `When` suffix that implies that something activates when the specified conditions are satisfied. The following properties are of type `ActivationConstraint`:
55-
56-
| Property | Description |
57-
| - | - |
58-
| `ExtensionConfiguration.LoadedWhen` | Controls when is the extension loaded. |
59-
| `CommandConfiguration.EnabledWhen` | Controls when the command is enabled (becomes callable). A command that isn't enabled might appear as a grayed out UI item. |
60-
| `CommandConfiguration.VisibleWhen` | Controls when a command is visible in the IDE. For example, when the menu item or command button appears in the UI. |
54+
Activation constraints can be used to configure a variety of VisualStudio.Extensibility functionalities, including the [loading of an extension](/dotnet/api/microsoft.visualstudio.extensibility.extensionconfiguration.loadedwhen), and the [enabled](/dotnet/api/microsoft.visualstudio.extensibility.commands.commandconfiguration.enabledwhen) or [visible](/dotnet/api/microsoft.visualstudio.extensibility.commands.commandconfiguration.visiblewhen) state of a command. The configuration types contain property of type `ActivationConstraint`, typically with a `When` suffix that implies that something activates when the specified conditions are satisfied.
6155

6256
## Activation constraint factory methods
6357

6458
This section shows the list of currently supported activation constraints. Each entry on the list is a factory method on the `ActivationConstraint` type.
6559

6660
| Term | Description |
6761
| -- | -- |
68-
| [`SolutionHasProjectCapability`](/dotnet/api/microsoft.visualstudio.extensibility.activationconstraint.solutionhasprojectcapability)(\<expression>=[`ProjectCapability`](/dotnet/api/microsoft.visualstudio.extensibility.projectcapability) | True whenever solution has a project with capabilities matching the provided subexpression. An expression can be something like `VB | CSharp`. For more about project capabilities, see [Project query API overview](../project/project.md). |
69-
| [`SolutionState`](/dotnet/api/microsoft.visualstudio.extensibility.activationconstraint.solutionstate)(\<state>=[`SolutionState`](/dotnet/api/microsoft.visualstudio.extensibility.solutionstate) | True when solution state matches the provided value, see [solution states](#solution-states) for list of values. |
70-
| [`ProjectAddedItem`](/dotnet/api/microsoft.visualstudio.extensibility.activationconstraint.projectaddeditem)(\<pattern>=\<regex>) | The term is true when a file matching the "pattern" is added to a project in the solution that is opened. |
7162
| [`ClientContext`](/dotnet/api/microsoft.visualstudio.extensibility.activationconstraint.clientcontext)(\<key>=[`ClientContextKey`](/dotnet/api/microsoft.visualstudio.extensibility.clientcontextkey), \<pattern>=\<regex>) | True when the provided client context key matches to regular expression. See [client context keys](#client-context-keys). |
63+
| [`ActiveProjectCapability`](/dotnet/api/microsoft.visualstudio.extensibility.activationconstraint.activeprojectcapability)(\<expression>=[`ProjectCapability`](/dotnet/api/microsoft.visualstudio.extensibility.projectcapability)) | True whenever solution has a project with capabilities matching the provided subexpression. An expression can be something like `VB | CSharp`. For more about project capabilities, see [Project query API overview](../project/project.md). |
64+
| [`ProjectAddedItem`](/dotnet/api/microsoft.visualstudio.extensibility.activationconstraint.projectaddeditem)(\<pattern>=\<regex>) | The term is true when a file matching the "pattern" is added to a project in the solution that is opened. |
65+
| [`SolutionHasProjectCapability`](/dotnet/api/microsoft.visualstudio.extensibility.activationconstraint.solutionhasprojectcapability)(\<expression>=[`ProjectCapability`](/dotnet/api/microsoft.visualstudio.extensibility.projectcapability)) | True whenever solution has a project with capabilities matching the provided subexpression. An expression can be something like `VB | CSharp`. For more about project capabilities, see [Project query API overview](../project/project.md). |
66+
| [`SolutionState`](/dotnet/api/microsoft.visualstudio.extensibility.activationconstraint.solutionstate)(\<state>=[`SolutionState`](/dotnet/api/microsoft.visualstudio.extensibility.solutionstate)) | True when solution state matches the provided value, see [solution states](#solution-states) for list of values. |
7267

7368
For compatibility reasons, the following legacy activation constraints are also supported:
7469

7570
| Term | Description |
7671
| -- | -- |
72+
| [`ActiveProjectBuildProperty`](/dotnet/api/microsoft.visualstudio.extensibility.activationconstraint.activeprojectbuildproperty)(\<property>=\<regex>) | The term is true when the selected project has the specified build property and the property value matches the regex pattern provided. |
73+
| [`ActiveProjectFlavor`](/dotnet/api/microsoft.visualstudio.extensibility.activationconstraint.activeprojectflavor)(\<guid>) | True whenever the selected project has a flavor matching the given project type GUID. |
7774
| [`SolutionHasProjectBuildProperty`](/dotnet/api/microsoft.visualstudio.extensibility.activationconstraint.solutionhasprojectbuildproperty)(\<property>=\<regex>) | The term is true when solution has a loaded project with the specified build property and property value matches to regex filter provided. |
7875
| [`SolutionHasProjectFlavor`](/dotnet/api/microsoft.visualstudio.extensibility.activationconstraint.solutionhasprojectflavor)(\<guid>) | True whenever a solution has project that is flavored (aggregated) and has a flavor matching the given project type GUID. |
7976

8077
## Solution states
8178

82-
The solution state refers to the state of the solution and its projects, whether a solution is loaded, whether it has zero, one, or multiple projects, and whether it is building.
83-
84-
The following table shows the possible solution states:
85-
86-
| State | Description |
87-
| -- | -- |
88-
| NoSolution | No solution loaded. |
89-
| Exists | A solution is opened but may be in loaded or loading state. |
90-
| FullyLoaded | A solution is opened and fully loaded. |
91-
| Empty | Solution contains no projects but may contain solution items. |
92-
| SingleProject | Solution contains a single project. |
93-
| MultipleProject | Solution contains multiple projects. |
94-
| Building | Solution is building. |
79+
The [solution state](/dotnet/api/microsoft.visualstudio.extensibility.solutionstate) refers to the state of the solution and its projects, whether a solution is loaded, whether it has zero, one, or multiple projects, and whether it is building.
9580

9681
Activation constraints that correspond to solution states can be combined in the same way as any other activation constraints. For example, you can combine an activation constraint that specifies a `FullyLoaded` solution and a `SingleProject` solution to capture single-project solutions when they are fully loaded.
9782

9883
```csharp
99-
this.EnabledWhen = And(ActivationConstraint.SolutionState(SolutionState.SingleProject), ActivationConstraint.SolutionState(SolutionState.FullyLoaded);
84+
this.EnabledWhen = ActivationConstraint.And(
85+
ActivationConstraint.SolutionState(SolutionState.SingleProject),
86+
ActivationConstraint.SolutionState(SolutionState.FullyLoaded));
10087
```
10188

10289
## Client context keys
10390

10491
Activation rules can also utilize the [client context](extension-anatomy.md#client-context) contents as parts of its expression.
10592

106-
Currently, the client context is limited to a small set of values in IDE state:
107-
108-
| Context key | Definition |
109-
| -- | -- |
110-
| Shell.ActiveSelectionUri | Full URI for the selected item in solution explorer. |
111-
| Shell.ActiveSelectionPath | Full path for the selected item in solution explorer. |
112-
| Shell.ActiveSelectionFileName | File name of the selected item in solution explorer. |
113-
| Shell.ActiveEditorContentType | Content type of the active editor view. |
114-
| Shell.ActiveEditorFileName | File name for the document that belongs to active editor view. |
93+
Currently, the client context is limited to a [small set of values](/dotnet/api/microsoft.visualstudio.extensibility.clientcontextkey.shell#properties) in IDE state.
11594

11695
## Next steps
11796

docs/extensibility/visualstudio.extensibility/inside-the-sdk/advanced-remote-ui.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ internal class MyToolWindowData
104104
}
105105

106106
[DataMember]
107-
public ObservableCollection<MyColor> Colors { get; } = new();
107+
public ObservableList<MyColor> Colors { get; } = new();
108108

109109
[DataMember]
110110
public AsyncCommand AddColorCommand { get; }
@@ -130,7 +130,7 @@ There are just a few noteworthy things in this code:
130130

131131
1. `MyColor.Color` is a `string` but it's used as a `Brush` when data bound in XAML, this is a capability provided by WPF.
132132
1. The `AddColorCommand` async callback contains a 2-second delay to simulate a long-running operation.
133-
1. We use [ObservableCollection\<T\>](/dotnet/api/system.collections.objectmodel.observablecollection-1), which is supported by Remote UI, to dynamically update the list view.
133+
1. We use [ObservableList\<T\>](microsoft.visualstudio.extensibility.ui.observablelist-1), which is an extended [ObservableCollection\<T\>](/dotnet/api/system.collections.objectmodel.observablecollection-1) provided by Remote UI to also support range operations, allowing better performance.
134134
1. `MyToolWindowData` and `MyColor` don't implement [INotifyPropertyChanged](/dotnet/api/system.componentmodel.inotifypropertychanged) because, at the moment, all properties are readonly.
135135

136136
## Handle long-running async commands

docs/extensibility/visualstudio.extensibility/inside-the-sdk/contributions-and-configurations.md

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ The Command Parenting sample contributes another class, a `Command`, to Visual S
4444
[VisualStudioContribution]
4545
internal class SampleCommand : Command
4646
{
47-
public SampleCommand(VisualStudioExtensibility extensibility)
48-
: base(extensibility)
47+
public SampleCommand()
4948
{
5049
}
5150
...
@@ -67,19 +66,19 @@ Most Visual Studio contribution classes require or allow configuration. For exam
6766
[VisualStudioContribution]
6867
internal class SampleCommand : Command
6968
{
70-
...
71-
public override CommandConfiguration CommandConfiguration => new("%SampleCommand.DisplayName%")
69+
/// <inheritdoc />
70+
public override CommandConfiguration CommandConfiguration => new("%CommandParentingSample.SampleCommand.DisplayName%")
7271
{
7372
Placements = new[]
7473
{
7574
// File in project context menu
76-
CommandPlacement.FromVsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), 1072),
75+
CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id: 1072, priority: 0),
7776

7877
// Project context menu
79-
CommandPlacement.FromVsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), 1026),
78+
CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id: 1026, priority: 0),
8079

8180
// Solution context menu
82-
CommandPlacement.FromVsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), 1043),
81+
CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id: 1043, priority: 0),
8382
},
8483
};
8584
...
@@ -89,7 +88,7 @@ internal class SampleCommand : Command
8988

9089
*Compile-time constants* are subject to additional limitations compared to normal properties, for example they must be readonly and their initialization code can't include references to non-static members or multi-statement imperative code blocks. These restrictions are enforced by the VisualStudio.Extensibility build tools and results in error messages like the following:
9190

92-
> Property SampleCommand.CommandConfiguration is a compile-time constant. References to user-defined non-static members are not supported when evaluating compile-time constant values.
91+
> An issue was encountered when evaluating the compile-time constant SampleCommand.CommandConfiguration. References to user-defined non-static members are not supported when evaluating compile-time constant values.
9392

9493
In general, the extension shouldn't reference *compile-time constant* configuration properties at run time.
9594

@@ -108,9 +107,7 @@ public abstract class Command : ExecutableCommandHandler, IVisualStudioContribut
108107
...
109108
```
110109

111-
On rare occasions, configuration properties are optional. For example, the `Extension` class has a virtual `ExtensionConfiguration` property which includes some less common configurations.
112-
113-
In certain cases, you may need to implement multiple configuration properties on the same class. This is common when extending `ExtensionPart` and implementing multiple interfaces, each one requiring its own configuration property.
110+
On rare occasions, configuration properties may be optional. In certain cases, you may need to implement multiple configuration properties on the same class. This is common when extending `ExtensionPart` and implementing multiple interfaces, each one requiring its own configuration property.
114111

115112
## Standalone configuration properties
116113

@@ -128,7 +125,7 @@ namespace CommandParentingSample;
128125
internal static class ExtensionCommandConfiguration
129126
{
130127
[VisualStudioContribution]
131-
public static ToolbarConfiguration ToolBar => new("%ToolBar.DisplayName%")
128+
public static ToolbarConfiguration ToolBar => new("%CommandParentingSample.ToolBar.DisplayName%")
132129
{
133130
Children = new[]
134131
{
@@ -140,28 +137,26 @@ internal static class ExtensionCommandConfiguration
140137

141138
Visual Studio contribution properties are also *compile-time constants* and are subject to the same limitations discussed earlier.
142139

143-
The [Markdown Linter](https://github.com/Microsoft/VSExtensibility/tree/main/New_Extensibility_Model/Samples/MarkdownLinter/TextViewEventListener.cs) project shows a sample of a Visual Studio contribution property being referenced by another configuration property:
140+
A of a Visual Studio contribution property can also reference another configuration property. For example:
144141

145142
```csharp
146-
internal static class MarkdownLinterExtensionContributions
143+
public static class MenuConfigurations
147144
{
148145
[VisualStudioContribution]
149-
internal static DocumentTypeConfiguration MarkdownDocumentType => new("markdown")
146+
public static CommandGroupConfiguration MyCommandGroup => new(GroupPlacement.KnownPlacements.ExtensionsMenu)
150147
{
151-
FileExtensions = new[] { ".md", ".mdk", ".markdown" },
152-
BaseDocumentType = DocumentType.KnownValues.Text,
148+
Children = new GroupChild[]
149+
{
150+
GroupChild.Menu(MyMenu),
151+
},
153152
};
154-
}
155153

156-
[VisualStudioContribution]
157-
internal class TextViewEventListener : ExtensionPart, ITextViewOpenClosedListener, ITextViewChangedListener
158-
{
159-
...
160-
public TextViewExtensionConfiguration TextViewExtensionConfiguration => new()
154+
[VisualStudioContribution]
155+
public static MenuConfiguration MyMenu => new("%MyMenu.DisplayName%")
161156
{
162-
AppliesTo = new[]
157+
Children = new[]
163158
{
164-
DocumentFilter.FromDocumentType(MarkdownLinterExtensionContributions.MarkdownDocumentType),
159+
MenuChild.Command<MyCommand>(),
165160
},
166161
};
167162
...

docs/extensibility/visualstudio.extensibility/inside-the-sdk/extension-anatomy.md

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,30 @@ An extension utilizing VisualStudio.Extensibility typically has several componen
1616

1717
## Extension instance
1818

19-
The starting point for each extension is an instance of `Microsoft.VisualStudio.Extensibility.Extension`. This instance contains the necessary methods for Visual Studio to query services provided by the extension. It also provides virtual methods for the extension to provide localized resources and extension-owned local services to be shared between the components of the extension.
20-
21-
Extension projects have their own class that derives from `Microsoft.VisualStudio.Extensibility.Extension` to customize certain aspects of the extension.
22-
23-
Extensions must have a class that derives from `Microsoft.VisualStudio.Extensibility.Extension`. For an example implementation, see [MarkdownLinter](https://github.com/microsoft/VSExtensibility/tree/main/New_Extensibility_Model/Samples/MarkdownLinter).
24-
25-
For extension developers that are familiar with the existing VS SDK APIs, this class is similar to `AsyncPackage` class that is used in the VS SDK extensibility model.
19+
Extensions must have a class that derives from [`Extension`](/dotnet/api/microsoft.visualstudio.extensibility.extension). For an example implementation, see [MarkdownLinter](https://github.com/microsoft/VSExtensibility/tree/main/New_Extensibility_Model/Samples/MarkdownLinter).
20+
21+
An instance of the `Extension` class is the starting point for the extension's execution. This instance contains the necessary methods for Visual Studio to query services provided by the extension. It also provides virtual methods for the extension to provide localized resources and extension-owned local services to be shared between the components of the extension.
22+
23+
The configuration for the `Extension` class also contains the [metadata](/dotnet/api/microsoft.visualstudio.extensibility.extensionconfiguration.metadata) for the extension which is shown in the Visual Studio [Manage Extensions window](/visualstudio/ide/finding-and-using-visual-studio-extensions?view=vs-2022#use-the-manage-extensions-dialog-box) and, for published extensions, on the [Visual Studio Marketplace](https://marketplace.visualstudio.com/).
24+
25+
```csharp
26+
[VisualStudioContribution]
27+
public class MarkdownLinterExtension : Extension
28+
{
29+
/// <inheritdoc/>
30+
public override ExtensionConfiguration ExtensionConfiguration => new()
31+
{
32+
Metadata = new(
33+
id: "MarkdownLinter.0cf26ba2-edd5-4419-8646-a55d0a83f7d8",
34+
version: this.ExtensionAssemblyVersion,
35+
publisherName: "Microsoft",
36+
displayName: "Markdown Linter Sample Extension",
37+
description: "Sample markdown linter extension"),
38+
};
39+
...
40+
```
41+
42+
For extension developers who are familiar with the existing VS SDK APIs, the `Metadata` contained in `ExtensionConfiguration` is used to generate the [.vsixmanifest](/visualstudio/extensibility/anatomy-of-a-vsix-package#the-vsix-manifest) file. Also, the `Extension` class is similar to the [`AsyncPackage`](/dotnet/api/microsoft.visualstudio.shell.asyncpackage) class that is used in the VS SDK extensibility model.
2643

2744
## VisualStudioExtensibility object
2845

0 commit comments

Comments
 (0)