MEF。如何将winform加载到winform容器中?

发布于 2024-09-26 15:15:17 字数 2897 浏览 1 评论 0原文

我决定尝试一下 MEF2 和 net3.5,我认为这会很容易,但现在我陷入了困境。一般来说,我的玩具的想法是我想要一个表单容器,我将在其中加载表单扩展并显示它们。我做了这段代码

我的扩展:


using System.ComponentModel.Composition;
using System.Windows.Forms;

namespace MyExtantion
{
    public interface IForm
    {
        void LoadForm(Form form);
    }

    [Export(typeof(IForm))]
    public partial class MyExtantion : Form, IForm
    {
        public MyExtantion()
        {
            InitializeComponent();
        }

        public void LoadForm(Form form)
        {
            MdiParent = form;
            Show();
        }

    }
}

和表单容器


using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System.Windows.Forms;

namespace FormsContainer
{
    public partial class FormContainer : Form
    {
        public FormContainer()
        {
            InitializeComponent();
        }

        private CompositionContainer _container;

        public interface IForm
        {
            void LoadForm(Form form);
        }

        [Import(typeof(IForm))]
        public IEnumerable Forms { get; set; }

        private bool Compose()
        {
            var catalog = new AggregateCatalog(
                new AssemblyCatalog(Assembly.GetExecutingAssembly()),
                new DirectoryCatalog("Extantions"));
            var batch = new CompositionBatch();
            batch.AddPart(this);

            _container = new CompositionContainer(catalog);

            try
            {
                _container.Compose(batch);
            }
            catch (CompositionException compositionException)
            {
                MessageBox.Show(compositionException.ToString());
                return false;
            }

            return true;
        }

        private void FormContainer_Load(object sender, EventArgs e)
        {
            if (Compose())
                foreach (IForm form in Forms)
                {
                    form.LoadForm(this);
                }
        }

    }
}

问题是我无法加载我的扩展并且出现此错误

{“组合保持不变。由于以下错误,更改被拒绝:组合产生了一个组合错误。下面提供了根本原因。查看 CompositionException.Errors 属性以获取更多详细信息。\ r\n\r\n1) 未找到与约束匹配的导出 '((exportDefinition.ContractName = \"FormsContainer.FormContainer+IForm\") && (exportDefinition.Metadata.ContainsKey(\"ExportTypeIdentity\") && \"FormsContainer.FormContainer+IForm\".Equals(exportDefinition.Metadata.get_Item(\"ExportTypeIdentity\"))))'。\r\n\r\n导致:无法设置 import 'FormsContainer.FormContainer 'FormsContainer.FormContainer' 部分上的 .Forms (ContractName=\"FormsContainer.FormContainer+IForm\")'。\r\nElement: FormsContainer.FormContainer.Forms (ContractName=\"FormsContainer.FormContainer+IForm\") --> ; FormsContainer.FormContainer\r\n"}

如何使用 MEF 实现它?我做错了什么?

I have decided to play a little bit with MEF2 and net3.5 and I have thought it would be easy but I am stuck now. Generally the idea of my toy is I want to have form containet where I am going to load form extensions and show them. I did this code

My extension:


using System.ComponentModel.Composition;
using System.Windows.Forms;

namespace MyExtantion
{
    public interface IForm
    {
        void LoadForm(Form form);
    }

    [Export(typeof(IForm))]
    public partial class MyExtantion : Form, IForm
    {
        public MyExtantion()
        {
            InitializeComponent();
        }

        public void LoadForm(Form form)
        {
            MdiParent = form;
            Show();
        }

    }
}

and form container


using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System.Windows.Forms;

namespace FormsContainer
{
    public partial class FormContainer : Form
    {
        public FormContainer()
        {
            InitializeComponent();
        }

        private CompositionContainer _container;

        public interface IForm
        {
            void LoadForm(Form form);
        }

        [Import(typeof(IForm))]
        public IEnumerable Forms { get; set; }

        private bool Compose()
        {
            var catalog = new AggregateCatalog(
                new AssemblyCatalog(Assembly.GetExecutingAssembly()),
                new DirectoryCatalog("Extantions"));
            var batch = new CompositionBatch();
            batch.AddPart(this);

            _container = new CompositionContainer(catalog);

            try
            {
                _container.Compose(batch);
            }
            catch (CompositionException compositionException)
            {
                MessageBox.Show(compositionException.ToString());
                return false;
            }

            return true;
        }

        private void FormContainer_Load(object sender, EventArgs e)
        {
            if (Compose())
                foreach (IForm form in Forms)
                {
                    form.LoadForm(this);
                }
        }

    }
}

The problem is I can not load my extantion and I have this error

{"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.\r\n\r\n1) No exports were found that match the constraint '((exportDefinition.ContractName = \"FormsContainer.FormContainer+IForm\") && (exportDefinition.Metadata.ContainsKey(\"ExportTypeIdentity\") && \"FormsContainer.FormContainer+IForm\".Equals(exportDefinition.Metadata.get_Item(\"ExportTypeIdentity\"))))'.\r\n\r\nResulting in: Cannot set import 'FormsContainer.FormContainer.Forms (ContractName=\"FormsContainer.FormContainer+IForm\")' on part 'FormsContainer.FormContainer'.\r\nElement: FormsContainer.FormContainer.Forms (ContractName=\"FormsContainer.FormContainer+IForm\") --> FormsContainer.FormContainer\r\n"}

How I can achieve it with MEF? and What I do wrong?

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

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

发布评论

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

评论(1

埋葬我深情 2024-10-03 15:15:17

您在两个不同的地方声明 IForm 接口。
如果您只引用一个接口,则两者都使用此代码可以正常工作。

You are declaring the IForm interface in two different places.
If you only reference one interface that both are using this code works properly.

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