Visual studio Visual Studio可扩展性:如何控制组件的加载顺序?

Visual studio Visual Studio可扩展性:如何控制组件的加载顺序?,visual-studio,vsix,vs-extensibility,vsixmanifest,Visual Studio,Vsix,Vs Extensibility,Vsixmanifest,我有一个VisualStudio扩展,它在同一个VSIX中包含一个包和一个标记器 加载包时,它会初始化一些东西,包括记录器。标记器使用记录器。这一切对我来说都是可行的,但在一台客户机器上,标记器在包之前加载,并且由于记录器尚未初始化而崩溃 如何向Visual Studio表示,它应该始终在加载标记器之前加载包? 软件包如下所示: [ProvideAutoLoad(VSConstants.UICONTEXT.NoSolution_string)] [ProvideAutoLoad(VSConsta

我有一个VisualStudio扩展,它在同一个VSIX中包含一个包和一个标记器

加载包时,它会初始化一些东西,包括记录器。标记器使用记录器。这一切对我来说都是可行的,但在一台客户机器上,标记器在包之前加载,并且由于记录器尚未初始化而崩溃

如何向Visual Studio表示,它应该始终在加载标记器之前加载包?

软件包如下所示:

[ProvideAutoLoad(VSConstants.UICONTEXT.NoSolution_string)]
[ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]
public sealed class EntrianInlineWatchPackage : Package ...
[Export(typeof(IViewTaggerProvider))]
[ContentType("C/C++")]
[TextViewRole(PredefinedTextViewRoles.Document)]
[TagType(typeof(ValueTag))]
public class ValueTaggerProvider : IViewTaggerProvider
{
    [Import]
    internal IClassifierAggregatorService AggregatorService;

    public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag
    {
        ...
        return buffer.Properties.GetOrCreateSingletonProperty("com.entrian.ValueTagger", delegate () {
            IClassifier classifier = AggregatorService.GetClassifier(buffer);
            return new ValueTagger(classifier, textView, buffer) as ITagger<T>;
        }) as ITagger<T>;
<Content>
  <VsPackage>|%CurrentProject%;PkgdefProjectOutputGroup|</VsPackage>
  <MefComponent>|%CurrentProject%|</MefComponent>
</Content>
标记器如下所示:

[ProvideAutoLoad(VSConstants.UICONTEXT.NoSolution_string)]
[ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]
public sealed class EntrianInlineWatchPackage : Package ...
[Export(typeof(IViewTaggerProvider))]
[ContentType("C/C++")]
[TextViewRole(PredefinedTextViewRoles.Document)]
[TagType(typeof(ValueTag))]
public class ValueTaggerProvider : IViewTaggerProvider
{
    [Import]
    internal IClassifierAggregatorService AggregatorService;

    public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag
    {
        ...
        return buffer.Properties.GetOrCreateSingletonProperty("com.entrian.ValueTagger", delegate () {
            IClassifier classifier = AggregatorService.GetClassifier(buffer);
            return new ValueTagger(classifier, textView, buffer) as ITagger<T>;
        }) as ITagger<T>;
<Content>
  <VsPackage>|%CurrentProject%;PkgdefProjectOutputGroup|</VsPackage>
  <MefComponent>|%CurrentProject%|</MefComponent>
</Content>
[导出(类型(IViewTaggerProvider))]
[内容类型(“C/C++”)]
[TextViewRole(预定义的textViewRoles.Document)]
[TagType(typeof(ValueTag))]
公共类ValueTaggerProvider:IViewTaggerProvider
{
[进口]
内部IClassifierAggregatorService聚合服务;
公共ITagger CreateTagger(ITextView textView,ITextBuffer buffer),其中T:ITag
{
...
返回buffer.Properties.GetOrCreateSingletonProperty(“com.entrian.ValueTagger”,委托(){
ICClassifier分类器=AggregatorService.GetClassifier(缓冲区);
将新的ValueTagger(分类器、文本视图、缓冲区)返回为ITagger;
})作为伊塔格;
vsixmanifest如下所示:

[ProvideAutoLoad(VSConstants.UICONTEXT.NoSolution_string)]
[ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]
public sealed class EntrianInlineWatchPackage : Package ...
[Export(typeof(IViewTaggerProvider))]
[ContentType("C/C++")]
[TextViewRole(PredefinedTextViewRoles.Document)]
[TagType(typeof(ValueTag))]
public class ValueTaggerProvider : IViewTaggerProvider
{
    [Import]
    internal IClassifierAggregatorService AggregatorService;

    public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag
    {
        ...
        return buffer.Properties.GetOrCreateSingletonProperty("com.entrian.ValueTagger", delegate () {
            IClassifier classifier = AggregatorService.GetClassifier(buffer);
            return new ValueTagger(classifier, textView, buffer) as ITagger<T>;
        }) as ITagger<T>;
<Content>
  <VsPackage>|%CurrentProject%;PkgdefProjectOutputGroup|</VsPackage>
  <MefComponent>|%CurrentProject%|</MefComponent>
</Content>

|%CurrentProject%;PkgdefProjectOutputGroup|
|%当前项目%|

谢谢!

您的软件包提供了日志记录服务。Visual Studio为此提供了完整的基础架构:

因此,在包代码中,您需要:

  • 创建一些表示服务契约的接口(例如
    IMyLogger

  • 注册此服务(此服务最终将在安装时进入注册表,以便VS以静态方式知道您的包实现此服务)

    而且,神奇的是,如果需要,VisualStudio应该加载包(这要感谢通过
    provideDevice
    属性声明的注册表设置)


    PS:注意,这将要求您在包和标记程序集都可以访问的程序集中定义
    IMyLogger
    。或者您可以使用适合您需要的知名接口。

    这看起来很完美,除了一件事:在包加载之前如何调用
    GetService
    ?在我当前的代码中,当除了我的包(例如Tagger)之外,它还需要一个服务,它调用包的
    GetService
    方法,但这一切的关键是,标记器在包之前加载,所以我不能这样做…?你不应该从标记器代码调用包的代码(所以不要从那里调用包的GetService方法).查看第二个链接(“如何:获取服务”):标记器代码不知道谁实现了SMyLogger服务,它通过标准与方法进行询问(碰巧您实现了两个方面,但这无关紧要,如果您愿意的话,这是某种依赖项注入+运行时发现机制)。我知道不该做什么。:-)我不明白的是:在您的示例中,
    ServiceProvider
    是什么?当我尝试调用
    ServiceProvider.GetService()
    时,我得到了“需要对象引用”,这似乎是合理的-我应该在哪个对象上调用
    GetService
    ?(我在
    Microsoft.VisualStudio.Shell
    中找到
    ServiceProvider
    -这是错误的吗?)您是否看到了包上的GetGlobalService静态方法(在第二个链接中,它位于“从工具窗口或控制容器获取服务”一章中)?是的,但是如果在加载任何包之前调用它,它可能会失败,这让我感到紧张-如果在加载任何包之前加载我的标记器会怎么样?(或者这是不可能的,因为标记器是由编辑器加载的,而编辑器本身就是一个包…?)