Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C中两个项目中的循环依赖#_C#_Circular Dependency - Fatal编程技术网

C# C中两个项目中的循环依赖#

C# C中两个项目中的循环依赖#,c#,circular-dependency,C#,Circular Dependency,我在一个名为ProjectA(ConsoleApplication)和ProjectB(ClassLibrary)的解决方案中有两个项目。ProjectA引用了ProjectB。一般来说,ProjectA在ProjectB中调用一个方法来做一些事情并将结果返回给ProjectA。但是,有时我需要ProjectB向ProjectA发送一些“附加”信息(更具体地说是调用ProjectA中的Console.WriteLine()方法)。为了实现这一点,我需要在ProjectB中引用ProjectA,但

我在一个名为ProjectA(ConsoleApplication)和ProjectB(ClassLibrary)的解决方案中有两个项目。ProjectA引用了ProjectB。一般来说,ProjectA在ProjectB中调用一个方法来做一些事情并将结果返回给ProjectA。但是,有时我需要ProjectB向ProjectA发送一些“附加”信息(更具体地说是调用ProjectA中的
Console.WriteLine()
方法)。为了实现这一点,我需要在ProjectB中引用ProjectA,但当我尝试这样做时,我得到以下错误:

无法添加对ProjectA的引用。将此项目添加为引用将导致循环依赖关系


我理解整个耦合概念,并且得到这个消息是有意义的,但是,在某些情况下,我需要向ProjectA发送额外的信息。有什么想法吗?

我建议你使用事件和听众。例如,您可以通过
Trace.WriteLine
从ProjectB发送消息,而在ProjectA中,您可以为跟踪添加订户。NET已经提供了一个
ConsoleTraceListener
类,用于将
Trace
消息路由到控制台。您可以通过以下方式从ProjectA添加侦听器:

Trace.Listeners.Add(new ConsoleTraceListener());
或者,如果您不想使用集成类,您可以在ProjectB中构建一个非常简单的“源”类,该类将公开一个以
Action
作为签名的事件(尽管我建议您为它创建一个委托),然后从ProjectA订阅它。通常,.NET类更灵活

项目b

public static class MyTrace
{
    public static event Action<string> MessageReceived;

    internal static void Broadcast(string message)
    {
        if (MessageReceived != null) MessageReceived(message);
    }
}

你不能这样做。如果项目相互调用,则它们应位于同一项目中。或者,代替ProjectB调用ProjectA,ProjectB可以公开它的信息,这样ProjectA就可以访问它


不能有循环依赖项。你怎么能?编译器如何知道首先构建哪个?您有一个基本的设计问题,这就是需要解决的问题。

我实际上会在ClassB上创建您自己的事件

public event EventHandler MySpecialHook;
EventHandler是的标准委托

public delegate void EventHandler(object sender, EventArgs e);
然后,在类A中,在创建了类B的实例之后,当B中发生了A应该知道的事情时,钩住事件处理程序进行通知。很像OnActivated、OnLostFocus、OnMouseMove或类似事件(但它们具有不同的委托签名)


实际上,创建具有循环依赖项的项目是可以成功编译的,但我强烈建议不要这样做。相反,组织项目,使其具有非循环依赖关系图

有很多方法可以解决这个问题,其中一些已经在其他答案中提到。一个尚未发布的是完全消除项目A和项目B之间的依赖关系,并创建第三个项目C,该项目定义了A和B通过其进行通信的接口。即:

namespace C
{
    public interface IFoo { void Frob(); }
    public interface IBar { void Qux(); }
}
然后使项目A和B引用项目C,并使它们的类实现IFoo、IBar等。当项目a中的方法需要对项目B中的对象调用Frob时,它通过获取IFoo而不是获取B中的某个类来实现


这有意义吗?

我的两个类都是静态的。很好的方法,尽管你激起了我的好奇心——你如何创建具有循环依赖关系的项目,并成功编译?
public class ClassB {

public event EventHandler MySpecialHook;

public void SomeMethodDoingActionInB()
{

    // do whatever you need to.
    // THEN, if anyone is listening (via the class A sample below)
    // broadcast to anyone listening that this thing was done and 
    // they can then grab / do whatever with results or any other 
    // properties from this class as needed.
    if( MySpecialHook != null )
        MySpecialHook( this, null );
 } 
}

public class YourClassA
{

   ClassB YourObjectToB;

   public YourClassA
   {
      // create your class
      YourObjectToB = new ClassB();
      // tell Class B to call your "NotificationFromClassB" method
      // when such event requires it
      YourObjectToB += NotificationFromClassB;
   }

   public void NotificationFromClassB( object sender, EventArgs e )
   {
      // Your ClassB did something that your "A" class needs to work on / with.
      // the "sender" object parameter IS your ClassB that broadcast the notification.
   }
}
namespace C
{
    public interface IFoo { void Frob(); }
    public interface IBar { void Qux(); }
}