Question

I created a small extension for the EF designer that adds a new property to the property window. I did this using a vsix project (new project -> c# -> extensibility -> vsix project). When I hit F5 the experimental VS instance starts up. I create a new project, add an entity data model and add an entity. However, my break points never get hit and I don't see the property. Any ideas as to what I might be doing wrong?

public class AggregateRootValue
{
    internal static XName AggregateRootElementName = XName.Get("AggregateRoot", "http://efex");

    private readonly XElement _property;
    private readonly PropertyExtensionContext _context;

    public AggregateRootValue(XElement parent, PropertyExtensionContext context)
    {
        _property = parent;
        _context = context;
    }

    [DisplayName("Aggregate Root")]
    [Description("Determines if an entity is an Aggregate Root")]
    [Category("Extensions")]
    [DefaultValue(true)]
    public string AggregateRoot 
    {
        get 
        {
            XElement child = _property.Element(AggregateRootElementName);
            return (child == null) ? bool.TrueString : child.Value;
        }
        set 
        {
            using (EntityDesignerChangeScope scope = _context.CreateChangeScope("Set AggregateRoot"))
            {
                var element = _property.Element(AggregateRootElementName);
                if (element == null)
                    _property.Add(new XElement(AggregateRootElementName, value));
                else
                    element.SetValue(value);
                scope.Complete();
            }
        }
    }
}

[Export(typeof(IEntityDesignerExtendedProperty))]
[EntityDesignerExtendedProperty(EntityDesignerSelection.ConceptualModelEntityType)]
public class AggregateRootFactory : IEntityDesignerExtendedProperty
{
    public object CreateProperty(XElement element, PropertyExtensionContext context)
    {
        var edmXName = XName.Get("Key", "http://schemas.microsoft.com/ado/2008/09/edm");
        var keys = element.Parent.Element(edmXName).Elements().Select(e => e.Attribute("Name").Value);

        if (keys.Contains(element.Attribute("Name").Value))
            return new AggregateRootValue(element, context);

        return null;
    }
}

EDIT: I put the code on Github: https://github.com/devlife/Sandbox

EDIT: After Adding the MEF component to the manifest as suggested, the extension still never loads. Here is a picture of the manifest:

VSIX Manifest

Was it helpful?

Solution

So the answer, as it turns out, is in how I setup my project. I put both classes inside the project which produces the VSIX file. By simply moving those classes into another project and setting that project as the MEF Component in the manifest (and thus copying the assembly) it worked like a charm!

OTHER TIPS

For VS2012, it is only needed to add Solution as MEF component also. Just add whole solution as MEF component also. Then it works surprisingly fine.

enter image description here

It seems the dll built by your project isn't automatically included in the generated VSIX package, and VS2013 doesn't give you options through the IDE to change this (that I can work out, anyway).

You have to manually open the project file and alter the XML. The property to change is IncludeAssemblyInVSIXContainer.

Seen here: How to include VSIX output in it's package?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top