Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Muitos componentes do SDK do VisualStudio.Extensibilidade, como manipuladores de comando e provedores de janela de ferramentas, são implementados como classes individuais. Para ajudar a compartilhar componentes entre essas classes, o SDK utiliza de injeção de dependência do .NET para instanciar essas classes conforme necessário. Para simplificar o compartilhamento de dados entre esses componentes, incentivamos os desenvolvedores de extensões a contribuir com seus componentes compartilhados para o gráfico de injeção de dependência também.
Adicionando serviços internos ao gráfico de injeção de dependência
Cada extensão no SDK do VisualStudio.Extensibility tem seu próprio gráfico de serviço que é criado quando a extensão é carregada pela primeira vez. As extensões podem substituir o método InitializeServices para adicionar os seus próprios serviços ao gráfico de injeção de dependência. Você pode consultar Markdown Linter para obter um exemplo de como usar a injeção de dependência para compartilhar um serviço.
Observação
Ao contrário do padrão IServiceProvider do SDK do Visual Studio, esses serviços só são visíveis para outros componentes dentro da mesma extensão e não se destinam a ser compartilhados com outras extensões.
Serviços fornecidos pelo VisualStudio.Extensibility SDK
Além dos serviços fornecidos pela extensão, o VisualStudio.Extensibility SDK adiciona os seguintes serviços ao gráfico ao criar a instância de extensão:
TraceSource: Uma instância compartilhada de TraceSource é adicionada ao gráfico que os componentes podem usar para registrar avisos e erros. Esses logs podem ser úteis para diagnosticar problemas com a extensão a partir de relatórios de clientes.VisualStudioExtensibility: instância de extensibilidade que expõe APIs para interagir com o Visual Studio, como documentos, editor, espaço de trabalho.
IServiceBroker: O agente de serviços pode ser usado para acessar serviços intermediados oferecidos pelo Visual Studio ou outros serviços que podem não fazer parte da área de superfícieVisualStudioExtensibility.IServiceProvider: O provedor de serviços pode ser usado para consultar serviços dentro do próprio gráfico de injeção de dependência da extensão. Esta instância não é a mesma instância que o provedor de serviços global no processo do Visual Studio para extensões em processo.
Serviços adicionais para extensões em processo
Para extensões em execução no processo, os seguintes serviços também estão disponíveis:
JoinableTaskFactoryeJoinableTaskContext: Ao executar como uma extensão em processo utilizando outros serviços do Visual Studio, pode ser necessário utilizar essas instâncias para interagir com o thread principal sem causar bloqueios. Para obter mais informações, consulte livro de receitas do Visual Studio Threading.AsyncServiceProviderInjection e MefInjection: Estas classes podem ser usadas para recuperar serviços internos oferecidos pela infraestrutura
IServiceProviderouMEFnos componentes de extensão do VisualStudio.Extensibility. Quando disponível, recomendamos utilizar primeiro os serviços oferecidos pelo SDK do VisualStudio.Extensibilidade.IAsyncServiceProvider2: Esta classe pode ser usada como uma alternativa paraAsyncServiceProviderInjectionconsultar serviços em execução do Visual Studio usando o métodoGetServiceAsync.
Métodos de extensão fornecidos pelo VisualStudio.Extensibility SDK
Os métodos de extensão para a instância IServiceCollection também podem ser usados para ajudar a adicionar serviços relacionados a recursos de extensibilidade:
- AddSettingsObservers: Este método é gerado quando uma extensão contribui com um SettingsCategory e pode ser chamado em
InitializeServicespara injetar serviços de observador para a categoria de configurações contribuídas. Você pode consultar SettingsSample para ver um exemplo desse método sendo usado.
Vida útil do serviço
Ao adicionar um novo serviço ao gráfico de injeção de dependência no método InitializeServices, existem três opções diferentes de ciclo de vida. Pode também consultar o exemplo sobre como diferentes opções de ciclo de vida são utilizadas numa extensão.
AddSingleton: Esses serviços compartilham o mesmo tempo de vida que a instância de extensão. Na maioria das vezes, usar "singleton services" é a escolha apropriada para uma extensão do "Visual Studio Extensibility SDK".AddTransient: Os serviços transitórios criam uma nova instância da classe de implementação ou chamam o método de fábrica sempre que um serviço o consulta. Como resultado, cada componente obtém sua própria instância do serviço.AddScoped: Este escopo só se aplica a classes que têm o atributoVisualStudioContributione serviços consultados por elas. No contexto do VisualStudio.Extensibility SDK, um escopo é definido pelo tempo de vida de um componente contribuído. Na maioria dos casos, esse tempo de vida é o mesmo que o tempo de vida da extensão, portanto, os serviços com escopo vs singleton se comportarão da mesma forma. A documentação fará uma observação especial se houver componentes contribuídos com diferentes durações.
Exemplo de caso de uso
Este exemplo demonstra como usar um objeto de fonte de dados partilhada entre uma implementação de janela de ferramentas e um manipulador de comando, usando injeção de dependência e InitializeServices.
No
MyExtension.InitializeServices,MyDataSourceé adicionado como um serviço singleton, pois é compartilhado entre componentes.MyToolWindowControlé adicionado como transitório porque cada instância da janela de ferramenta deve ter sua própria instância exclusiva do controle hospedado.Em
MyToolWindow, injetamosIServiceProviderno construtor para evitar a inicialização precoce doMyToolWindowControle, em vez disso, o consultamos viaGetRequiredServicequando necessário.
[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) { }
}