试图弄清楚这个MEF组合错误意味着什么

时间:2010-12-06 03:46:46

标签: c# winforms mef

我对我在尝试完成对.ComposeParts(this)的调用时遇到的以下异常有疑问:

  

该组合物产生单一   构图错误。根本原因是   提供如下。回顾一下   CompositionException.Errors属性   有关更多详细信息。

     

1)出口   “CustomersModule.CustomerMenu   (ContractName =“ModLibrary.IMenu”)'是   不能分配给类型   “System.Collections.Generic.IEnumerable`1 [[ModLibrary.IMenu,   ModLibrary,版本= 1.0.0.0,   文化=中性,   公钥=空]]”。

     

导致:无法设置导入   “ModAppWorks.Host.Menus   (ContractName =“ModLibrary.IMenu”)'on   部分'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

如果IMenu 需要实施IEnumerable,是否有人看到我可能做错的事情?

1 个答案:

答案 0 :(得分:6)

当您导入导出集合时,您需要使用ImportMany属性明确指出它。像这样更改属性属性:

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

您还应该能够排除合同(“typeof(Menu)”参数),因为您导入的是导出的相同类型。保留合同的导出属性。

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