I have a Visual Studio extension which includes a Package and a Tagger in the same VSIX.
When the Package is loaded, it initializes a few things, including a logger. The Tagger uses the logger. This all works for me, but on one customer machine the Tagger is loaded before the Package, and crashes because the logger hasn't been initialized yet.
How do I express to Visual Studio that it should always load the Package before loading the Tagger?
The Package looks like this:
[ProvideAutoLoad(VSConstants.UICONTEXT.NoSolution_string)]
[ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]
public sealed class EntrianInlineWatchPackage : Package ...
The Tagger looks like this:
[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>;
The vsixmanifest looks like this:
<Content>
<VsPackage>|%CurrentProject%;PkgdefProjectOutputGroup|</VsPackage>
<MefComponent>|%CurrentProject%|</MefComponent>
</Content>
Thanks!
Your package offers a logging service. Visual Studio has a full infrastructure for this: How to: Provide a Service
What you need, in the package code, is therefore to:
create some interface that represents the service contract (like IMyLogger
for example)
register this service (this will eventually go in the registry at setup time so VS knows in a static way your package implements this)
[ProvideService(typeof(SMyLogger))] public sealed class EntrianInlineWatchPackage : Package {. . .}
implement the service (follow the link above for more).
In all other packages or addins or extensions that will use this service (so in your Tagger code), you should be able to get a reference to this service, for example:
IMyLogger logger = ServiceProvider.GetService(typeof(SMyLogger)) as IMyLogger;
and, magically, Visual Studio should load the package, if needed (thanks to the registry settings declared through the ProvideService
attribute).
PS: Note this will require that you define IMyLogger
in an assembly accessible by both the Package and the Tagger assemblies. Or you could use a well known interface that suits your need.