If you have multiple classes that export the IPersonPart
interface that we created in the previous workshop, MEF won't know which part to import into the MyImportedPersonPart
property, and will throw an exception when you call CompositionInitializer.SatisfyImports
. However, by turning the MyImportedPersonPart
property into an array/collection, and using the ImportMany
attribute instead of Import
, multiple parts can be imported into the MyImportedPersonPart
property.
In this workshop, we'll modify what we have from the previous two workshops, and make multiple parts available to the MainPage
class.
Chapter14Sample
project, named AnotherPersonPart.cs
, and add the following code to it:
using System.ComponentModel.Composition;
namespace Chapter14Sample
{
[Export(typeof(IPersonPart))]
public class AnotherPersonPart : IPersonPart
{
public string Name { get; set; }
public AnotherPersonPart()
{
Name = "Marge Simpson";
}
}
}
As you can see, it's simply another implementation of the IPersonPart
interface, essentially identical to the PersonPart
class, but with a different value assigned to its Name
property in its constructor.
PersonPart
or AnotherPersonPart
) it should import into the MyImportedPersonPart
property on the MainPage
class. We can make the MyImportedPersonPart
property accept multiple parts by turning it into an array, and decorating it with the ImportMany
attribute instead of the Import
attribute, like so:
[ImportMany]
public IPersonPart[] MyImportedPersonParts { get; set; }
TextBlock
to display the value of the imported part's Name
property. We now need to modify this code to display the value of the Name
property for all of the imported parts. Instead of the TextBlock
, let's display the names in a ListBox
control. The full code for the MainPage
class follows, with the required changes in bold:
using System.ComponentModel.Composition;
using System.Windows.Controls;
namespace Chapter14Sample
{
public partial class MainPage : UserControl
{
[ImportMany]
public IPersonPart[] MyImportedPersonParts { get; set; }
public MainPage()
{
InitializeComponent();
CompositionInitializer.SatisfyImports(this);
var list = new ListBox();
list.ItemsSource = MyImportedPersonParts;
list.DisplayMemberPath = "Name";
LayoutRoot.Children.Add(list);
}
}
}
ListBox
that has been added to the view. Go ahead and add additional classes to your project that implement the IPersonPart
interface and export themselves. They too will automatically appear in the list.