I have two projects in a solution named ProjectA (ConsoleApplication) and ProjectB (ClassLibrary). ProjectA has a reference to ProjectB. Generally speaking, ProjectA calls a method in ProjectB to do some stuff and return the results to ProjectA. Sometimes however, I need ProjectB to send some "additional" information to ProjectA (more specifically to call the Console.WriteLine()
method in ProjectA). To achieve this, I need to refer ProjectA in ProjectB, but when I try to do that, I get the following error:
A reference to ProjectA could not be added. Adding this project as a reference would cause a circular dependency
.
I understand the whole coupling concept and it does make sense to get this message, however, I need to send additional information to ProjectA in some cases. Any ideas?
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?
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*/
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With