Попытка выяснить, что означает эта ошибка MEF Composition - PullRequest
5 голосов
/ 06 декабря 2010

У меня вопрос о следующем исключении, которое я получил при попытке завершить вызов .ComposeParts(this):

Композиция вызвала единственную ошибку композиции.Основная причина приведена ниже.Просмотрите свойство CompositionException.Errors для получения более подробной информации.

1) Экспорту CustomersModule.CustomerMenu (ContractName = "ModLibrary.IMenu") 'нельзя присвоить тип' System.Collections.Generic.IEnumerable`1.[[ModLibrary.IMenu, ModLibrary, версия = 1.0.0.0, культура = нейтральная, PublicKeyToken = null]].

В результате: невозможно установить импорт 'ModAppWorks.Host.Menus (ContractName = "ModLibrary.IMenu")" на части "ModAppWorks.Host".Элемент: ModAppWorks.Host.Menus (ContractName = "ModLibrary.IMenu") -> ModAppWorks.Host

Там есть часть, которая выглядит так, как будто ошибка означает, что IMenu должен реализовать IEnumerable.Вот мой код композиции:

static class Program
{
    [STAThread]
    static void Main()
    {
        Host host = new Host();
        host.Run();
    }
}

class Host
{
    #region Init
    public Host()
    { }
    #endregion

    #region Functions
    public void Run()
    {
        Compose();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new AppHost());
    }

    private void Compose()
    {
        var agrCatalog = new AggregateCatalog();
        var dirCatalog = new DirectoryCatalog(Path.GetDirectoryName
            (Assembly.GetExecutingAssembly().Location) + "..\\..\\..\\Extensions", "*.dll");
        var asmCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());

        agrCatalog.Catalogs.Add(dirCatalog);
        agrCatalog.Catalogs.Add(asmCatalog);

        var hostContainer = new CompositionContainer(agrCatalog);
        hostContainer.ComposeParts(this);
    }
    #endregion

    #region Properties
    [Import(typeof(IMenu))]
    public IEnumerable<IMenu> Menus { get; set; }
    #endregion

Я импортирую класс, экземпляры которого ToolStripMenuItem.Мой образец экспорта:

[Export(typeof(IMenu))]
public class CustomerMenu : IMenu
{
    #region Fields
    private System.Windows.Forms.ToolStripMenuItem CustomerMainMenu;
    private System.Windows.Forms.ToolStripSeparator mnuSeparator;
    private System.Windows.Forms.ToolStripMenuItem CustomersMenuItem;
    #endregion

    #region Init
    public CustomerMenu()
    {
        InitializeComponent();
        // 
        // CustomerMenu
        // 
        this.CustomerMainMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
        this.mnuSeparator,
        this.CustomersMenuItem});
        this.CustomerMainMenu.Name = "CustomerMenu";
        this.CustomerMainMenu.Size = new System.Drawing.Size(94, 20);
        this.CustomerMainMenu.Text = "Customer Menu";
        // 
        // toolStripMenuItem1
        // 
        this.mnuSeparator.Name = "toolStripMenuItem1";
        this.mnuSeparator.Size = new System.Drawing.Size(149, 6);
        // 
        // Customers
        // 
        this.CustomersMenuItem.Name = "Customers";
        this.CustomersMenuItem.Size = new System.Drawing.Size(152, 22);
        this.CustomersMenuItem.Text = "Customers";
    }

    #endregion

    #region Functions
    private void InitializeComponent()
    {
        this.CustomerMainMenu = new System.Windows.Forms.ToolStripMenuItem();
        this.mnuSeparator = new System.Windows.Forms.ToolStripSeparator();
        this.CustomersMenuItem = new System.Windows.Forms.ToolStripMenuItem();
    }

    #endregion

Если для реализации IEnumerable требуется IMenu, а не , а не , кто-нибудь видит что-то, что я могу делать неправильно?

1 Ответ

6 голосов
/ 06 декабря 2010

Когда вы импортируете коллекцию экспорта, вам необходимо четко указать это с помощью атрибута ImportMany. Измените свой атрибут собственности следующим образом:

[ImportMany(typeof(IMenu))] 
public IEnumerable<IMenu> Menus { get; set; } 

Вы также должны иметь возможность исключить контракт (параметр "typeof (Menu)"), поскольку вы импортируете тот же тип, который был экспортирован. Оставьте контракт на атрибуты экспорта, хотя.

[ImportMany] 
public IEnumerable<IMenu> Menus { get; set; } 
...