Circular Dependency in Two Projects in C#

后端 未结 4 1283
轻奢々
轻奢々 2020-12-20 12:42

I have two projects in a solution named ProjectA (ConsoleApplication) and ProjectB (ClassLibrary). ProjectA has a reference to ProjectB. Generally speaking, ProjectA calls a

相关标签:
4条回答
  • 2020-12-20 12:51

    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.
       }
    }
    
    0 讨论(0)
  • 2020-12-20 12:54

    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?

    0 讨论(0)
  • 2020-12-20 12:54

    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.

    0 讨论(0)
  • 2020-12-20 13:12

    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*/
    };
    
    0 讨论(0)
提交回复
热议问题