1

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

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

我如何向 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>;

vsixmanifest 如下所示:

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

谢谢!

4

1 回答 1

2

您的软件包提供了日志记录服务。Visual Studio 有一个完整的基础结构:如何:提供服务

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

  1. 创建一些代表服务合同的接口(IMyLogger例如)

  2. 注册这个服务(这最终会在设置时进入注册表,所以 VS 以静态方式知道你的包实现了这个)

    [提供服务(类型(SMyLogger))]
    公共密封类 EntrianInlineWatchPackage : 包
    {。. .}
  3. 实施服务(点击上面的链接了解更多)。

在将使用此服务的所有其他包或插件或扩展中(因此在您的标记器代码中),您应该能够获得对此服务的引用,例如:

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

并且,如果需要,Visual Studio 会神奇地加载包(感谢通过ProvideService属性声明的注册表设置)。

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

于 2015-10-29T08:54:48.863 回答