如何在这种情况下避免循环依赖?

时间:2017-02-16 01:12:44

标签: c# dependency-injection stack-overflow circular-dependency

当前程序导致stackoverflow异常,我知道原因。我怎么能在这里避免循环依赖。虽然这些类相互依赖,但我怎么能让这三个类彼此独立(想象一下这些类中的方法相互引用)。

namespace CircularDependency_1
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            B b = new B();
            Console.WriteLine("executed");
            Console.ReadLine();
        }
    }

    public class B
    {
        public A a;

        public B()
        {
            a = new A();
            Console.WriteLine("Creating B");
        }
    }

    public class A
    {
        public B b;

        public A()
        {      
             b = new B();
            Console.WriteLine("Creating A");
        }
    }

    public class C
    {
        public A a;
        public B b;

        public C ()
        {
            a = new A();
            b = new B();
            Console.WriteLine("Creating C");
        }
    }

}

2 个答案:

答案 0 :(得分:1)

你不应该是新的对象。相反,您需要将它们作为参数传递给构造函数。您需要将代码重构为:

public class A {
  B _b;
  public A(B b) {
    _b = b;
    Console.WriteLine("Creating A");
  }
}
public class B {
  A _a;
  public B(A a) {
    _a = a;
    Console.WriteLine("Creating B");
  }
}
public class C {
  A _a;
  B _b;
  public C (A a, B b) {
    _a = a;
    _b = b;
    Console.WriteLine("Creating C");
  }
}

然后你需要将A(或B)中的函数重构为另一个类D:

public class A {
  D _d;
  public A(D d) {
    _d = d;
    Console.WriteLine("Creating A");
  }
}
public class B {
  A _a;
  D _d;
  public B(A a, D d) {
    _a = a;
    _d = d;
    Console.WriteLine("Creating B");
  }
}

public class C {
  A _a;
  B _b;
  public C (A a, B b) {
    _a = a;
    _b = b;
    Console.WriteLine("Creating C");
  }
}

public class D {
  public D () {
    Console.WriteLine("Creating D");
  }
}

然后,您可以将对象创建为

D d = new D();
A a = new A(d);
B b = new B(a, d);
C c = new C(a, b);
Console.WriteLine("executed");
Console.ReadLine();

有关如何重构类以删除循环引用的信息,请参阅Circular Dependency in constructors and Dependency Injection

答案 1 :(得分:0)

这不是依赖注入,而是在构造函数中创建它。 您应该将A和B构造函数保持为空,并在C:

中执行类似的操作
public class C
    {
        public A a;
        public B b;

        public C ()
        {
            a = new A();
            b = new B();
            a.setB(b);
            b.setA(a);
        }
    }

另一方面,你应该检查你是否真的需要这个双重参考。

编辑: 我发现你并没有真正使用C类。如果你想在main中做,那就是同样的事情:

 static void Main(string[] args)
    {
        A a = new A();
        B b = new B();
        a.setB(b);
        b.setA(a);
    }