Extended properties MEF usage is incompatible with VS MEF


VS has built-in support for multiple MEF catalogs via the VsCatalogNameAttribute (see http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.extensibilityhosting.vscatalognameattribute.aspx).

Using this support, another catalog can contribute extensions to the VS global composition container, using the appropriate VsExportSharingPolicy (see http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.extensibilityhosting.vsexportsharingpolicy.aspx and explained http://blogs.clariusconsulting.net/pga/vs-10-beta-1-exporting-mef-parts-from-a-vs-package-part-1).

This works perfect for things like exposing text editor adornments, outliners and the like. That is, a custom catalog CAN provide exports to the global VSMEF container so that other components (i.e. the editor, or the EF designer) can retrieve those extensions.

However, I couldn't make this work at all with the EF designer. Turns out (apparently in my reflector investigations), that the EscherExtensionPointManager is the culprit, since it's doing this highly suspicious work:

private void Init()
ComposablePartCatalog catalog = (PackageManager.Package.GetService(typeof(SComponentModel)) as IComponentModel).GetCatalog("Microsoft.VisualStudio.Default");
this._compositionContainer = new CompositionContainer(catalog, new ExportProvider[0]);

From that point on, it's completely against the VSMEF behavior, since the EFAnnotatableElementDescriptor<TEFElement>.LoadPropertyDescriptorExtensions now uses THAT container to lookup exports, rather than the IComponentModel.DefaultExportProvider!

Investigating further, this reveals a more serious issue with the given approach: all exports from the VS MEF default catalog will get instantiated twice because of this custom private composition container, even when their part creation policy might indicate a shared instance. This is because this code is pulling just the catalog, and then building a new container. Exports on the VS global container will not be reused here, but will be instantiated again.

And the worse part, not even the omniprescent IServiceProvider export in VS works, which works on every other place within VS MEF :S
    public IServiceProvider ServiceProvider { get; set; }
Yes, someone could use ServiceProvider.GlobalServiceProvider, and any number of other workarounds. But the question remains: should this particular area adhere to VS extensibility in a more compatible way?

The attached solution contains 2 VSIX projects:
  • FailsToImportFromCustomCatalog: showcases how using a custom catalog makes an EF extended property dissapear. But at the same time showcases that a simple editor adornment works just fine, custom catalog or not.
  • FailsToImportServiceProvider: shows a straightforward VSIX with no custom catalog, package or anything. Just an export that fails when you import SVsServiceProvider, and succeeds when you don't.

file attachments

Closed Dec 13, 2016 at 8:30 PM by RoMiller
EF Team Triage: We are transitioning this project to GitHub (https://github.com/aspnet/EntityFramework6). As part of this transition we are bulk closing a large number of issues in order that our new issue tracker will accurately reflect the work that our team is planning to complete on the EF6.x code base.

Moving forwards, our team will be fixing bugs, implementing small improvements, and accepting community contributions to the EF6.x code base. Larger feature work and innovation will happen in the EF Core code base (https://github.com/aspnet/EntityFramework). Closing a feature request in the EF6.x project does not exclude us implementing the feature in EF Core. In fact, a number of popular feature requests for EF have already been implemented in EF Core (alternate keys, batching in SaveChanges, etc.).

This is a bulk message to indicate that this issue was closed and not ported to the new issue tracker. The reasons for not porting this particular issue to GitHub may include:
  • It was a bug report that does not contain sufficient information for us to be able to reproduce it
  • It was a question, but sufficient time has passed that it's not clear that taking the time to answer it would provide value to the person who asked it
  • It is a feature request that we are realistically not going to implement on the EF6.x code base
    Although this issue was not ported, you may still re-open it in the new issue tracker for our team to reconsider (https://github.com/aspnet/EntityFramework6/issues). We will no longer be monitoring this issue tracker for comments, so please do not reply here.


RoMiller wrote Nov 29, 2012 at 11:33 PM

EF Team Triage: We should look at doing this in EF6. We may accept a contribution for this once the designer is OSS.

RoMiller wrote Jan 16, 2013 at 8:49 PM

We are only taking minimal changes to the designer in EF6 because we are still converting the code base to open source. We'll consider this bug for the next release.

We would accept a contribution once the designer is OSS.