Your assumptions that assemblies cannot cross reference each other is incorrect. It's a pain to set up, and not easy to do through Visual Studio, IIRC, but it's doable.
First, we create 3 text files:
A.cs
:
using B;
namespace A
{
public class AA
{
public AA(BB val)
{
}
}
}
B.cs
:
using A;
namespace B
{
public class BB
{
public BB(AA val)
{
}
}
}
And, A_prime.cs
:
namespace A
{
public class AA
{
public AA()
{
}
}
}
Note that these classes are not meant to be useful or usable. Just to demonstrate the point - which is that we have two possible sources for A
- one in which we stub out or "work around" our need for a dependency on B
, and the other where we do not.
We then compile:
csc /out:A.dll /target:library A_prime.cs
csc /out:B.dll /target:library /reference:A.dll B.cs
csc /out:A.dll /target:library /reference:B.dll A.cs
End result - we have two assemblies that cross-reference each other1.
Similarly, within the .NET framework itself, we have plenty of cross-referencing happening - System.dll
, System.Xml.dll
and System.Configuration.dll
are all mutually cross-referencing. Although they probably have a more sophisticated build setup than the above - using a single source file and symbols to perform the bootstrapping, rather than separate source files.
And finally, to address namespaces - Namespaces are a logical grouping of functionality. Multiple assemblies may contribute types to a single namespace. A single assembly can contribute types to multiple namespaces. There is no logical reason why types within multiple namespaces should not be able to reference2 each other in both directions.
1This works provided the version of csc
you're using defaults to assigning a version number of 0.0.0.0 if there's no AssemblyVersion
attribute in the source. If that's not the case for a particular instance of csc
(I seem to remember it was different on some older ones), you may need to apply this attribute to ensure that the two compilations of A.dll
produce an assembly with the same identity.
Similarly, details like strong naming may make the process more laborious.
2"Little-r" reference, not "Big-r" reference. E.g. different types just using each other. Not reference in "What is a reference in C#?" terms.