Circular Dependency in Two Projects in C#

半腔热情 提交于 2019-11-29 13:15:52

I suggest you to use events and listeners. You can, for example, send messages from ProjectB through Trace.WriteLine while, in ProjectA, you would add a subscriber for the trace. .NET already offers a ConsoleTraceListener class, to route Trace messages to the Console. You can add a listener from ProjectA through:

Trace.Listeners.Add(new ConsoleTraceListener());

Alternatively, if you don't want to use the integrated classes, you can build a very simple "source" class in ProjectB which will exposes an event with Action<string> as its signature (although I'd suggest you to create a delegate for it), then subscribe to it from ProjectA. Generally, .NET classes are more flexible.

ProjectB

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

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

ProjectA

MyTrace.MessageReceived += s =>
{
    /*Operate*/
};

It is actually possible to create projects that have circular dependencies that compile successfully but I strongly recommend against it. Instead, organize your projects so that they have an acyclic dependency graph.

There are a number of ways to solve this problem, several of which have been mentioned in other answers. One not yet posted is to eliminate the dependency between project A and project B entirely, and create a third project, C, that defines the interfaces that A and B communicate over. That is:

namespace C
{
    public interface IFoo { void Frob(); }
    public interface IBar { void Qux(); }
}

And then make projects A and B reference project C, and make their classes implement IFoo, IBar, and so on. When a method in project A needs to call Frob on an object in project B, it does so by obtaining an IFoo, rather than obtaining some class in B.

Does that make sense?

You can't do this. If the projects call each other, they should be in the same project. Or, instead of ProjectB calling ProjectA, ProjectB could make it's information public, so ProjectA could access it.

You can't have a circular dependency. How could you? How would the compiler know which to build first? You have a fundamental design issue and that's what needs to be fixed.

DRapp

I would actually create your own event on ClassB

public event EventHandler MySpecialHook;

EventHandler is a standard delegate of

public delegate void EventHandler(object sender, EventArgs e);

Then, in your Class A, after creating your instance of ClassB, hook into the event handler for notification when something occurs in B that A should know about. Much like an OnActivated, OnLostFocus, OnMouseMove or similar events (but they have delegate different signatures)

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.
   }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!