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

发布于 2024-10-06 08:26:06 字数 3460 浏览 2 评论 0原文

我对尝试完成对 .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,有人会发现我可能做错了什么吗?

I have a question about the following exception I received trying to complete a call to .ComposeParts(this):

The composition produced a single
composition error. The root cause is
provided below. Review the
CompositionException.Errors property
for more detailed information.

1) The export
'CustomersModule.CustomerMenu
(ContractName="ModLibrary.IMenu")' is
not assignable to type
'System.Collections.Generic.IEnumerable`1[[ModLibrary.IMenu,
ModLibrary, Version=1.0.0.0,
Culture=neutral,
PublicKeyToken=null]]'.

Resulting in: Cannot set import
'ModAppWorks.Host.Menus
(ContractName="ModLibrary.IMenu")' on
part 'ModAppWorks.Host'. Element:
ModAppWorks.Host.Menus
(ContractName="ModLibrary.IMenu") -->
ModAppWorks.Host

There is a part there that seems like the error means that IMenu must implement IEnumerable. Here is my composition code:

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

I am importing a class that instances a ToolStripMenuItem. My export sample:

[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

If IMenu is not required to implement IEnumerable, does anyone see something I might be doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝海 2024-10-13 08:26:06

当您导入导出集合时,您需要使用 ImportMany 属性对其进行明确说明。像这样更改您的属性属性:

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

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

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

When you're importing a collection of exports, you need to be explicit about it by using the ImportMany attribute. Change your property attribute like this:

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

You should also be able to exclude the contract (the "typeof(Menu)" parameter) since you're importing the same type that was exported. Leave the contract on the Export attributes though.

[ImportMany] 
public IEnumerable<IMenu> Menus { get; set; } 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文