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

时间:2015-10-25 11:12:04

标签: visual-studio vsix vs-extensibility vsixmanifest

我有一个Visual Studio扩展,在同一个VSIX中包含一个Package和一个Tagger。

加载Package时,它会初始化一些内容,包括记录器。 Tagger使用记录器。这一切都适合我,但在一台客户机器上,Tagger在Package之前加载,并因为记录器尚未初始化而崩溃。

如何向Visual Studio表示在加载Tagger之前应始终加载包?

包看起来像这样:

[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>;

Tagger看起来像这样:

<Content>
  <VsPackage>|%CurrentProject%;PkgdefProjectOutputGroup|</VsPackage>
  <MefComponent>|%CurrentProject%|</MefComponent>
</Content>

vsixmanifest看起来像这样:

{{1}}

谢谢!

1 个答案:

答案 0 :(得分:2)

您的软件包提供日志记录服务。 Visual Studio具有完整的基础结构:How to: Provide a Service

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

  1. 创建一些代表服务合同的界面(例如IMyLogger

  2. 注册此服务(这将最终在设置时进入注册表,因此VS以静态方式知道您的包实现了这一点)

    [ProvideService(typeof(SMyLogger))]
    public sealed class EntrianInlineWatchPackage : Package
    {. . .}
  3. 实施服务(点击上面的链接了解更多信息)。

  4. 在将使用此服务的所有其他包或插件或扩展程序中(在您的Tagger代码中),您应该能够get a reference to this service,例如:

    IMyLogger logger = ServiceProvider.GetService(typeof(SMyLogger)) as IMyLogger;
    

    并且,奇怪的是,Visual Studio应该在需要时加载包(感谢通过ProvideService属性声明的注册表设置)。

    PS:请注意,这将要求您在Package和Tagger程序集都可访问的程序集中定义IMyLogger。或者您可以使用适合您需求的众所周知的界面。