Współtworzenie i konfiguracje

Składniki rozszerzeń można uwidaczniać w programie Visual Studio, wyprowadzając je z określonych klas bazowych, a także definiując pewne właściwości i używając różnych atrybutów.

Współtworzenie programu Visual Studio

Celem rozszerzenia programu Visual Studio jest współtworzenie nowych funkcji w programie Visual Studio. Jest to osiągane przez rozszerzenie jednej z wielu klas, takich jak Command, ToolWindowlub ExtensionPart i zastosowanie atrybutu VisualStudioContribution .

Ten artykuł odwołuje się do przykładowego rozszerzenia Command Parenting w celu wyjaśnienia pojęć związanych z współtworzenia i konfigurowania składników rozszerzenia.

Każde rozszerzenie VisualStudio.Extensibility musi współtworzyć co najmniej jedną Extension klasę:

namespace CommandParentingSample;

[VisualStudioContribution]
public class CommandParentingSampleExtension : Extension
{
    /// <inheritdoc/>
    protected override void InitializeServices(IServiceCollection serviceCollection)
    {
        base.InitializeServices(serviceCollection);
    }
}

Klasa Extension jest pierwszą wystąpieniem klasy rozszerzenia i umożliwia dodanie własnych usług do klasy, która ma być używana do IServiceCollection wstrzykiwania zależności.

Przykład Elementu nadrzędnego polecenia współtworzy inną klasę , do Commandprogramu Visual Studio:

[VisualStudioContribution]
internal class SampleCommand : Command
{
    public SampleCommand()
    {
    }
    ...

Podczas rozszerzania klasy bazowej dostarczonej przez zestaw VISUALStudio.Extensibility SDK możesz wiedzieć, czy chcesz użyć atrybutu VisualStudioContribution , sprawdzając, czy klasa bazowa implementuje IVisualStudioContributionClass (i ExtensionCommand nie).

Klasy kontrybucyjne programu Visual Studio są z opóźnieniem tworzone pojedynczo: tworzone jest tylko jedno wystąpienie, a jego tworzenie jest opóźnione, dopóki program Visual Studio nie będzie musiał z nim wchodzić w interakcje (na przykład gdy Command użytkownik po raz pierwszy wywołuje wystąpienie).

Infrastruktura rozszerzenia VisualStudio.Extensibility umożliwia również odbieranie usług za pośrednictwem wstrzykiwania zależności jako parametrów konstruktora klas współtworzenia programu Visual Studio (zobacz Usługi udostępniane przez zestaw SDK do wstrzykiwania), w tym wszelkie usługi dodane do IServiceCollection metody w Extension klasie InitializeServices .

Program Visual Studio często wymaga, aby unikatowy identyfikator był skojarzony z współtworzeniami. W większości przypadków infrastruktura VisualStudio.Extensibility używa pełnej nazwy klasy współtworzenia programu Visual Studio jako identyfikatora współtworzenia. Na przykład identyfikator powyższej Extension klasy to CommandParentingSample.CommandParentingSampleExtension. Warto dokładnie wybrać nazwę typu i przestrzeń nazw klas kontrybucyjnych programu Visual Studio, ponieważ mogą one być wyświetlane w dziennikach programu Visual Studio i komunikatach o błędach.

Konfigurowanie kontrybucjów programu Visual Studio

Większość klas kontrybucyjnych programu Visual Studio wymaga lub zezwala na konfigurację. Na przykład klasa abstrakcyjna Command wymaga implementacji CommandConfiguration właściwości określającej co najmniej nazwę wyświetlaną polecenia i opcjonalnie inne właściwości, takie jak jej umieszczanie.

[VisualStudioContribution]
internal class SampleCommand : Command
{
    /// <inheritdoc />
    public override CommandConfiguration CommandConfiguration => new("%CommandParentingSample.SampleCommand.DisplayName%")
    {
        Placements = new[]
        {
            // File in project context menu
            CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id: 1072, priority: 0),

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

            // Solution context menu
            CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id:  1043, priority: 0),
        },
    };
    ...

CommandConfigurationjest stałą czasu kompilacji, co oznacza, że jego wartość jest obliczana podczas kompilowania rozszerzenia i jest uwzględniona w manifeście rozszerzenia (extension.json). Program Visual Studio może odczytać manifest rozszerzenia bez ładowania samego rozszerzenia, co zapewnia lepszą wydajność.

Stałe czasu kompilacji podlegają dodatkowym ograniczeniom w porównaniu z normalnymi właściwościami, na przykład muszą być czytelne, a ich kod inicjowania nie może zawierać odwołań do niestatywnych elementów członkowskich lub bloków imperatywnych z wieloma instrukcjami. Te ograniczenia są wymuszane przez narzędzia kompilacji VisualStudio.Extensibility i powoduje wyświetlenie komunikatów o błędach, takich jak następujące:

Wystąpił problem podczas obliczania stałej czasu kompilacji SampleCommand.CommandConfiguration. Odwołania do niestacjonowanych elementów członkowskich zdefiniowanych przez użytkownika nie są obsługiwane podczas oceniania wartości stałych czasu kompilacji.

Ogólnie rzecz biorąc, rozszerzenie nie powinno odwoływać się do właściwości konfiguracji stałej w czasie kompilacji w czasie wykonywania.

Można łatwo zidentyfikować właściwości konfiguracji stałej czasu kompilacji, ponieważ ich definicja ma CompileTimeEvaluation atrybut .

public abstract class Command : ExecutableCommandHandler, IVisualStudioContributionClass
{
    ...
    /// <summary>
    /// Gets the configuration for this command. The value of this property is evaluated at compile time
    /// when building the Visual Studio extension.
    /// </summary>
    [CompileTimeEvaluation]
    public abstract CommandConfiguration CommandConfiguration { get; }
    ...

W rzadkich przypadkach właściwości konfiguracji mogą być opcjonalne. W niektórych przypadkach może być konieczne zaimplementowanie wielu właściwości konfiguracji w tej samej klasie. Jest to powszechne podczas rozszerzania i implementowania ExtensionPart wielu interfejsów, z których każdy wymaga własnej właściwości konfiguracji.

Właściwości konfiguracji autonomicznej

Jak opisano powyżej, klasy współtworzenia programu Visual Studio definiują pojedynczą klasę, która zwykle uwidacznia co najmniej jedną stałą właściwości konfiguracji w czasie kompilacji. Wartości właściwości konfiguracji są zapisywane jako metadane rozszerzenia.

Niektóre funkcje rozszerzalności wymagają określenia metadanych rozszerzenia, które nie są powiązane z żadną klasą i są istotne samodzielnie lub mają być odwoływalne przez inne konfiguracje. Kilka przykładów to definicje menu, paska narzędzi i typu dokumentu. Jest to osiągane przez zastosowanie atrybutu VisualStudioContribution do statycznej właściwości konfiguracji readonly.

Właściwości współtworzenia programu Visual Studio można umieścić w dowolnej klasie.

Przykład Elementu nadrzędnego polecenia definiuje pasek narzędzi, deklarując statyczną właściwość typu ToolbarConfiguration i oznaczając ją jako VisualStudioContribution.

namespace CommandParentingSample;

internal static class ExtensionCommandConfiguration
{
    [VisualStudioContribution]
    public static ToolbarConfiguration ToolBar => new("%CommandParentingSample.ToolBar.DisplayName%")
    {
        Children = new[]
        {
            ToolbarChild.Command<SampleCommand>(),
        },
    };
}

Właściwości współtworzenia programu Visual Studio są również stałymi czasu kompilacji i podlegają tym samym ograniczeniom, które zostały omówione wcześniej.

Właściwość współtworzenia programu Visual Studio może również odwoływać się do innej właściwości konfiguracji. Na przykład:

public static class MenuConfigurations
{
    [VisualStudioContribution]
    public static CommandGroupConfiguration MyCommandGroup => new(GroupPlacement.KnownPlacements.ExtensionsMenu)
    {
        Children = new GroupChild[]
        {
            GroupChild.Menu(MyMenu),
        },
    };

    [VisualStudioContribution]
    public static MenuConfiguration MyMenu => new("%MyMenu.DisplayName%")
    {
        Children = new[]
        {
            MenuChild.Command<MyCommand>(),
        },
    };
    ...

Typy przeznaczone do definiowania właściwości współtworzenia programu Visual Studio implementują IVisualStudioContributionProperty interfejs i są oznaczone atrybutem CompileTimeEvaluation w celu udokumentowania, że ich wartości są oceniane podczas kompilowania rozszerzenia.

[CompileTimeEvaluation]
public sealed class DocumentTypeConfiguration : IVisualStudioContributionProperty ...

Wskazówki dotyczące nie odwoływania się do właściwości konfiguracji stałej w czasie kompilacji w czasie wykonywania dotyczą również właściwości współtworzenia programu Visual Studio.

Jeśli unikatowy identyfikator jest wymagany dla właściwości współtworzenia programu Visual Studio, jego pełna nazwa (zawierająca pełną nazwę typu i nazwa właściwości) jest używana przez infrastrukturę VisualStudio.Extensibility jako identyfikator. Na przykład unikatowy identyfikator konfiguracji paska narzędzi omówiony w tym miejscu to CommandParentingSample.ExtensionCommandConfiguration.ToolbarConfiguration.