【问题标题】:Circular Reference循环参考
【发布时间】:2008-12-12 14:32:48
【问题描述】:

我正在寻找一种好的模式来解决 Windows 窗体应用程序中的以下循环引用:

  • Assembly 1 包含一个带有 Infragistics 菜单项“.Show”ing a Form in Assembly 2 的 Windows 窗体
  • Assembly 2 包含一个带有 Infragistics 菜单项“.Show”ing a Form in Assembly 1 的 Windows 窗体

整个应用程序中的菜单通常具有相同的项目。因此,Assembly 1 和 Assembly 2 都相互引用以“新建”彼此的表单并显示它们。

关于大小的说明:我的应用是一个现有的应用,所以情况并不像上面两个组装的情况那么简单。但是如果我能简单地解决上述问题(可能不实现 a ,我可以将它应用到更大的应用程序(大约 20 个组件,所有组件都有几种跨组件相互弹出的表单)。

我已经考虑了一些解决方案,但它们似乎都很麻烦。我缺少一个简单的解决方案吗?

【问题讨论】:

    标签: .net winforms circular-dependency


    【解决方案1】:

    您可以(在这两种情况下)使按钮简单地引发一个事件。 shell exe 引用了这两个程序集,并连接了 even 以显示另一种形式。

    所以 exe 知道这两者;两种形式都不知道对方。

    例如(同一个概念):

    using System;
    using System.Windows.Forms;
    class Form1 : Form
    {
        public event EventHandler Foo;
        public Form1()
        {
            Button btn = new Button();
            btn.Click += delegate { if(Foo!=null) Foo(this, EventArgs.Empty);};
            Controls.Add(btn);
        }
    }
    class Form2 : Form
    {
        public event EventHandler Bar;
        public Form2()
        {
            Button btn = new Button();
            btn.Click += delegate { if (Bar!= null) Bar(this, EventArgs.Empty); };
            Controls.Add(btn);
        }
    }
    static class Program
    {
        [STAThread]
        static void Main()
        {
            ShowForm1();
            Application.Run();
        }
        static void ShowForm1()
        {
            Form1 f1 = new Form1();
            f1.Foo += delegate { ShowForm2(); };
            f1.Show();
        }
        static void ShowForm2()
        {
            Form2 f2 = new Form2();
            f2.Bar += delegate { ShowForm1(); };
            f2.Show();
        }
    }
    

    【讨论】:

    • -1,导致可执行文件必须知道这两个窗口之间的连接 - 使用接口!
    • @BeowulfOF - 这是相当荒谬的。将整个 IoC/DI 框架放在这样的示例中是不合理的!如果没有 IoC/DI,exe 必须知道创建它们的具体类型。老实说,我很伤心......
    • 我考虑过使用事件,甚至开始在一个小案例中实现它。我最终可能会使用该解决方案。但是,考虑到我拥有的程序集和表单的数量,这似乎很麻烦。如果可能的话,我正在寻找一种影响更小的方法来在整个应用上实施该解决方案。
    【解决方案2】:

    您是否考虑过创建第三个程序集并将所有公共代码移到第三个程序集中?

    【讨论】:

    • 我不确定我是否听从了你的建议,约翰。如果我将所有“new...show”调用放在第三个程序集中,每个程序集都需要引用它并且它引用所有其他程序集,所以我仍然是循环的。
    • 不,所有的通用代码都在第三个。所以其他两个都依赖第三个,第三个什么都不依赖。
    【解决方案3】:

    使用组件工厂或组件编写器,例如MEF,在不引用组件源程序集的情况下创建实例。

    【讨论】:

      【解决方案4】:

      如何使用接口? 您可以构建包含接口的第三个库,每个窗口都从自身实现一个接口,并引用另一个窗口的接口。

      【讨论】:

      • 我认为会涉及到接口。但是,我仍然需要创建一个实例,所以我的代码类似于: IMyClass x = new MyClass();所以仍然需要引用包含 MyClass 的程序集。我现在正在尝试用反射做一些事情,以消除程序集参考。
      • 如果你需要,IMyClass = new MyClass,那么你肯定需要过度考虑你的模型。应该是 IMyClass = ObjectFromBaseClass.GetMyClassInstance。
      【解决方案5】:

      目前,我决定使用反射来弹出需要弹出的窗口。我不再需要直接引用它们,实际上我可以更轻松地添加组件,而无需创建所有交叉引用的程序集。

      我查看了 MEF,但不幸的是,我使用的是 VS2003,而不是 VS2008。这个建议让我走上了简单反思的道路。

      谢谢。

      【讨论】:

        猜你喜欢
        • 2014-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-01
        • 1970-01-01
        • 2021-12-02
        • 2016-02-19
        相关资源
        最近更新 更多