C# 接口 class 和对象依赖性和设计问题(代码分离)

C# Interface class and object dependencies AND design issue (code separation)

工作的第一天,我得到了一个已经不在公司的人的代码。一位实习生在我之前就接触到了代码,并且真的在上面做了很多工作! 所以情况是这样的。

Project A

namespace A{
    public class Evil { ... }
    public interface A1 { 
        Evil[] Evils
        {
            get;
            set;
        } 
        Evil getSomeEvilValue();
    }

    public class Hello : A1{
        public void some_func(){
            // reference to Project B 
            B.World w = new B.World();  // <--- Dependency on B!! Thank you intern!
            w.Run();
        }

        #region A1 implementation
        Evil[] evils;
        Evil[] Evils
        {
            get{return evils;}
            set{evils = value;}
        } 
        Evil getSomeEvilValue(){return new Evil();}
        #endregion
    }  
}

在另一个项目 B

Project B
    namespace B{
    public class World{
        public void Run(){
            ...
        }
    }  
}

新要求指定项目 B 必须与 A1 接口!!这将创建循环引用!所以我认为解决方案是创建第三个项目,Interfaces,并更改 A 和 B 以引用新项目。

但问题是我该如何处理 A1 对 class Evil 的依赖??

Project Interfaces
namespace Interfaces
{
    public interface A1
    {
        Evil[] Evils   // <---- what do i do here?? IEvil? 
        {
            get;
            set;
        } 
        Evil getSomeEvilValue();  // <----- What do i do here???
    }
 }

非常感谢你们的帮助!

使用控制反转

  1. 提取 A 和 B 知道的项目的接口 -> AB-Interfaces

  2. 创建一个作为应用程序入口点的项目,它代表所谓的 "Composition root" - 在这里您引用 A 和 B 并将引用传递给 类(因此 B 会在构造函数中请求 A,如 属性,...)并且 A 会请求 B(不在构造函数中,否则您将再次产生循环依赖;)

您也可以使用 DI 控制器来做到这一点,但现在可以做到这一点。

查看代码示例 here

在您的代码中:

Project A
namespace A {
        public class Hello : A1{
            public Hello(IWorld world){
                w.run(this);
            }
    }
}

Project B
namespace B {
    public class World : IWorld {
        public run(A1 a1){
            ...
        }
    }
}

Project I
namespace I {
    public interace A1{}
    public interface IWorld { run(A1); }
}

project Comp
namespace Comp {
    public class AppEntry {
        IWorld w = new World();
        A1 a1 = new Hello(w);
    }
}