Mef, Problem Loading XAP and Advice for communication

Sep 17, 2010 at 4:07 PM
Edited Sep 17, 2010 at 4:09 PM

Hi guys, I'm using the DeployementCatalog version for importing a single xap extension.

This is a code snippet of my version:

 

public partial class MainPage : UserControl, IPartImportsSatisfiedNotification
    {
        [Import]
        public IDeploymentCatalogService CatalogService { get; set; }

        //[ImportMany(AllowRecomposition = true)]
        //public Lazy<UserControl, IWidgetMetadata>[] Widgets { get; set; }

        [Import(AllowRecomposition = true)]
        public Lazy<UserControl, IWidgetMetadata> Widget { get; set; }

        public MainPage()
        {
            InitializeComponent();
            CompositionInitializer.SatisfyImports(this);
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            CatalogService.AddXap("HelloMEF.Extension.xap");
        }

        public void OnImportsSatisfied()
        {
            WidgetContainer.Items.Clear();

            //foreach (var widget in Widgets)
            //{
            //    if (widget.Metadata.Vendor == WidgetVendor.MyVendorSample)
            //        WidgetContainer.Items.Add(widget.Value);
            //}

            if (Widget.Metadata.Vendor == WidgetVendor.MyVendorSample)
                WidgetContainer.Items.Add(Widget.Value);
        }
    }
}

 

 

While the version with ImportMany attribute works well, the other version (Import only) when

 CompositionInitializer.SatisfyImports(this);

instruction is executed, MEF throws this error:

System.ComponentModel.Composition.ChangeRejectedException was unhandled by user code
  Message=The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) No valid exports were found that match the constraint '(((exportDefinition.ContractName == "System.Windows.Controls.UserControl") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "System.Windows.Controls.UserControl".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity")))) AndAlso (exportDefinition.Metadata.ContainsKey("Vendor") AndAlso HelloMEF.WidgetVendor.IsInstanceOfType(exportDefinition.Metadata.get_Item("Vendor"))))', invalid exports may have been rejected.

Resulting in: Cannot set import 'HelloMEF.MainPage.Widget (ContractName="System.Windows.Controls.UserControl")' on part 'HelloMEF.MainPage'.
Element: HelloMEF.MainPage.Widget (ContractName="System.Windows.Controls.UserControl") -->  HelloMEF.MainPage

 

The other problem that I'm trying to resolve is the communication between the Main App and the Widget. I've read Glenn Block post about EventAggregator. The proble is: how to obtain a reference of the container from the Widget. In particular, how to to this code:

var customEvent = _container.GetExportedObject<CustomCompositionEvent>();

from the Widget?

Thanks in advance, Regards Lorenzo.

Dec 7, 2010 at 10:02 PM

Same problem here.  If your class has an [Export] attribute you can use DeploymentCatalogService to load a Xap fine, but get rid of the attribute and use 

CompositionInitializer.SatisfyImports(this);

and suddenly MEF wants to recompose everything under the sun, and fails.
Dec 7, 2010 at 10:05 PM

As for your second question, why would you need the composition container?