Udostępnij przez


Wstrzykiwanie zależności w rozszerzeniach VisualStudio.Extensibility

Wiele składników zestawu VisualStudio.Extensibility SDK, takich jak programy obsługi poleceń i dostawcy okien narzędzi, są implementowane jako poszczególne klasy. Aby ułatwić udostępnianie składników między tymi klasami, zestaw SDK używa iniekcji zależności platformy .NET, aby utworzyć wystąpienia tych klas zgodnie z potrzebami. Aby uprościć udostępnianie danych między tymi składnikami, zachęcamy twórców rozszerzeń do dodawania współużytkowanych składników do diagramu wstrzykiwania zależności.

Dodawanie usług wewnętrznych do grafu iniekcji zależności

Każde rozszerzenie w zestawie VisualStudio.Extensibility SDK ma własny graf usługi tworzony podczas pierwszego ładowania rozszerzenia. Rozszerzenia mogą zastąpić metodę InitializeServices, aby dodać własne usługi do grafu iniekcji zależności. Możesz zapoznać się z Markdown Linter jako przykład użycia wstrzykiwania zależności do udostępniania usługi.

Notatka

W przeciwieństwie do wzorca IServiceProvider zestawu VISUAL Studio SDK te usługi są widoczne tylko dla innych składników w ramach tego samego rozszerzenia i nie są przeznaczone do udostępniania innym rozszerzeń.

Usługi udostępniane przez zestaw VisualStudio.Extensibility SDK

Oprócz usług udostępnianych przez rozszerzenie zestaw VisualStudio.Extensibility SDK dodaje następujące usługi do grafu podczas tworzenia wystąpienia rozszerzenia:

  • TraceSource: współużytkowane wystąpienie usługi TraceSource jest dodawane do grafu, którego składniki mogą używać do rejestrowania ostrzeżeń i błędów. Te logi mogą być przydatne do diagnozowania problemów z raportów klientów dotyczących rozszerzenia.

  • VisualStudioExtensibility: Instancja rozszerzalności uwidaczniająca wewnętrzne API, umożliwiające interakcję z programem Visual Studio, takich jak dokumenty, edytor czy obszar roboczy.

  • IServiceBroker: Broker usług może służyć do uzyskiwania dostępu do usług obsługiwanych przez brokera oferowanych przez program Visual Studio lub inne usługi, które mogą nie być częścią obszaru powierzchni VisualStudioExtensibility.

  • IServiceProvider: Dostawca usług może służyć do wykonywania zapytań o usługi w ramach wykresu iniekcji zależności rozszerzenia. To wystąpienie nie jest tym samym wystąpieniem co globalny dostawca usług w procesie programu Visual Studio dla rozszerzeń w procesie przetwarzania.

Dodatkowe usługi dla rozszerzeń będących w trakcie realizacji

W przypadku rozszerzeń uruchomionych w procesie dostępne są również następujące usługi:

  • JoinableTaskFactory i JoinableTaskContext: w przypadku uruchamiania jako rozszerzenia w procesie korzystającego z innych usług programu Visual Studio może być konieczne użycie tych wystąpień do interakcji z głównym wątkiem bez powodowania zakleszczenia. Aby uzyskać więcej informacji, zobacz podręcznik wątkowy programu Visual Studio.

  • AsyncServiceProviderInjection i MefInjection: te klasy mogą być używane do odzyskiwania usług wewnątrzprocesowych oferowanych przez komponenty rozszerzeń VisualStudio.Extensibility przy użyciu infrastruktury IServiceProvider lub MEF. Jeśli jest dostępna, zalecamy najpierw korzystanie z usług oferowanych przez zestaw VisualStudio.Extensibility SDK.

  • IAsyncServiceProvider2: ta klasa może służyć jako alternatywa dla AsyncServiceProviderInjection do wykonywania zapytań dotyczących usług programu Visual Studio w procesie przy użyciu metody GetServiceAsync.

Metody rozszerzeń udostępniane przez zestaw VisualStudio.Extensibility SDK

Metody rozszerzające stosowane na wystąpieniu IServiceCollection mogą również służyć do dodawania usług związanych z funkcjami rozszerzalności.

  • AddSettingsObservers: ta metoda jest generowana, gdy rozszerzenie dodaje KategorieUstawień i może być wywoływana w InitializeServices w celu dodania usług obserwatora do dodanej kategorii ustawień. Aby zapoznać się z przykładem używanej metody, możesz zapoznać się z SettingsSample.

Okresy istnienia usługi

Podczas dodawania nowej usługi do grafu iniekcji zależności w metodzie InitializeServices dostępne są 3 różne opcje okresu istnienia. Możesz również zajrzeć do przykładu , aby poznać, jak różne opcje cyklu życia są używane w rozszerzeniu.

  • AddSingleton: te usługi mają ten sam okres istnienia co wystąpienie rozszerzenia. W większości przypadków użycie usług singletonowych jest odpowiednim wyborem dla rozszerzenia zestawu SDK Visual Studio Extensibility.

  • AddTransient: Usługi przejściowe tworzą nowe wystąpienie klasy implementacji lub wywołują metodę fabrycznej za każdym razem, gdy usługa wysyła do niej zapytanie. W rezultacie każdy składnik otrzymuje własne wystąpienie usługi.

  • AddScoped: ten zakres dotyczy tylko klas, które mają VisualStudioContribution atrybut i usługi, których dotyczy zapytanie. W kontekście zestawu VisualStudio.Extensibility SDK zakres jest definiowany przez okres istnienia dostarczonego składnika. W większości przypadków ten cykl życia jest taki sam jak cykl życia rozszerzenia, więc usługi o określonym zasięgu a usługi pojedyncze będą działać tak samo. Dokumentacja zamieści specjalne uwagi, jeśli istnieją składniki z różnymi okresami istnienia.

Przykładowy przypadek użycia

W tym przykładzie pokazano, jak używać współdzielonego obiektu źródła danych między implementacją okna narzędzi a obsługą poleceń, przy użyciu wstrzykiwania zależności i InitializeServices.

  • W MyExtension.InitializeServicesMyDataSource jest dodawana jako pojedyncza usługa, ponieważ jest współdzielona między komponentami. MyToolWindowControl jest dodawany jako przejściowy, ponieważ każde wystąpienie okna narzędziowego powinno mieć własne unikatowe wystąpienie hostowanego elementu sterującego.

  • W MyToolWindowwprowadzamy IServiceProvider w konstruktorze, aby uniknąć wczesnego inicjowania MyToolWindowControl i zamiast tego wysyłać do niego zapytania za pośrednictwem GetRequiredService w razie potrzeby.

[VisualStudioContribution]
public class MyExtension : Extension
{
    protected override void InitializeServices(IServiceCollection serviceCollection)
    {
        // Always make sure to call the base method to add required services.
        base.InitializeServices(serviceCollection);

        serviceCollection.AddSingleton<MyDataSource>();
        serviceCollection.AddTransient<MyToolWindowControl>();
    }
}

[DataContract]
public class MyDataSource : NotifyPropertyChangedObject
{
}

public class MyToolWindowControl : RemoteUserControl
{
    public MyToolWindowControl(MyDataSource dataSource) : base(dataContext)
    {
    }
}

[VisualStudioContribution]
public class MyToolWindow : ToolWindow
{
    private readonly IServiceProvider serviceProvider;

    public MyToolWindow(IServiceProvider serviceProvider)
    {
    }

    public override Task<IRemoteUserControl> GetContentAsync(CancellationToken cancellationToken)
    {
        var control = this.serviceProvider.GetRequiredService<MyToolWindowControl>();
        return Task.FromResult<IRemoteUserControl>(control);
    }
}

[VisualStudioContribution]
public class MyCommand : Command
{
    public MyCommand(MyDataSource dataSource) { }
}