4

I'm writing a Visual Studio extension, and I need create my own IWpfTextViewHost (CodeEditor Window). This can be done via the ITextEditorFactoryService but this has to be loaded via the MEF framework.

But my import is always null, but I can't seem to work out why my import is null. I have a rought idea how MEF works, is there a method to call the CompositionContainerof Visual Studio itself? Or does the vsix project construct this container? If so, based on what settings?

public class MyViewHost {

   [Import]
   public ITextEditorFactoryService TextEditorFactory { get; set; }

   public IWpfTextViewHost CreateViewHost(ITextBuffer textBuffer) 
   {
      var textView = this.TextEditorFactory.CreateTextView(textBuffer);
      return this.TextEditorFactory.CreateTextViewHost(textView, true);
   }

}

Edit this is the relevant part of the extension.vsixmanifest

  <Assets>
      <Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="Build%CurrentProject%" Path="|dllName;PkgdefProjectOutputGroup|" />
      <Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" Path="dllName" />
  </Assets>
  • What does your .vsixmanifest file look like? – nejcs Aug 20 '18 at 19:33
  • Hello, I added the relevant part of the extension.vsixmanifest to it. It has an asset as MefComponent – Tim Ramandt Aug 21 '18 at 09:14
  • 1
    How do you get/create an instance of `MyViewHost`? This class does not implement any known interface and you are not exporting it as a MEF component. It seems like this is not retrieved via MEF component registry so there is no way that imports will be populated. – nejcs Aug 22 '18 at 19:17

1 Answers1

1

I've found the answer based on @nejcs response and this gist. I'll post the solution:

[Export(typeof(IMyViewHost))]
public class MyViewHost : IMyViewHost
{
    [Import]
    public ITextEditorFactoryService TextEditorFactory { get; set; }

    public IWpfTextViewHost CreateViewHost(ITextBuffer textBuffer)
    {
        var textView = this.TextEditorFactory.CreateTextView(textBuffer);
        return this.TextEditorFactory.CreateTextViewHost(textView, true);
    }

IMyViewHost is an interface with the CreateViewHost Method. The SatisfyImportsOnce must be called in the constructor of the extension command class and the IMyViewHost must be imported in this extension command class.

  • I think that Export'ing MyViewHost is not needed to resolve the ITextEditorFactoryService [Import]. I.e. , SatisfyImportsOnce( ) is what solves the issue. If you Export for other reasons, then do so of course, but I don't think that the Export is needed for the [Import] resolution. Please correct me if I'm wrong. – Coder Jul 12 '23 at 23:55