Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the .NET CLR have a circular dependency? [duplicate]

In the .NET BCL there are circular references between:

  • System.dll and System.Xml.dll
  • System.dll and System.Configuration.dll
  • System.Xml.dll and System.Configuration.dll

Here's a screenshot from .NET Reflector that shows what I mean:

enter image description here

How Microsoft created these assemblies is a mystery to me. Is a special compilation process required to allow this? I imagine something interesting is going on here.

like image 215
Drew Noakes Avatar asked Aug 22 '09 17:08

Drew Noakes


People also ask

What is circular dependency in C#?

In software engineering, a circular dependency is a relation between two or more modules which either directly or indirectly depend on each other to function properly. Such modules are also known as mutually recursive.

How do you avoid circular dependencies?

To reduce or eliminate circular dependencies, architects must implement loose component coupling and isolate failures. One approach is to use abstraction to break the dependency chain. To do this, you introduce an abstracted service interface that delivers underlying functionality without direct component coupling.

What causes circular dependency?

A circular dependency occurs when two classes depend on each other. For example, class A needs class B, and class B also needs class A. Circular dependencies can arise in Nest between modules and between providers. While circular dependencies should be avoided where possible, you can't always do so.

What is circular dependency in asp net core?

A circular dependency was detected for the service of type 'UserService'. UserService -> PhoneService -> UserService. It even directly points out the exact services which depend on each other. Note that in some cases, the circle could be much larger.


3 Answers

I can only tell how the Mono Project does this. The theorem is quite simple, though it gives a code mess.

They first compile System.Configuration.dll, without the part needing the reference to System.Xml.dll. After this, they compile System.Xml.dll the normal way. Now comes the magic. They recompile System.configuration.dll, with the part needing the reference to System.Xml.dll. Now there's a successful compilation with the circular reference.

In short:

  • A is compiled without the code needing B and the reference to B.
  • B is compiled.
  • A is recompiled.
like image 86
Dykam Avatar answered Oct 28 '22 22:10

Dykam


RBarryYoung and Dykam are onto something. Microsoft uses internal tool which uses ILDASM to disassemble assemblies, strip all internal/private stuff and method bodies and recompile IL again (using ILASM) into what is called 'dehydrated assembly' or metadata assembly. This is done every time public interface of assembly is changed.

During the build, metadata assemblies are used instead of real ones. That way cycle is broken.

like image 44
Srdjan Jovcic Avatar answered Oct 28 '22 23:10

Srdjan Jovcic


It can be done the way Dykam described but Visual Studio blocks you from doing it.

You'll have to use the command-line compiler csc.exe directly.

  1. csc /target:library ClassA.cs

  2. csc /target:library ClassB.cs /reference:ClassA.dll

  3. csc /target:library ClassA.cs ClassC.cs /reference:ClassB.dll


//ClassA.cs
namespace CircularA {
    public class ClassA {
    }
}


//ClassB.cs
using CircularA;
namespace CircularB {
    public class ClassB : ClassA  {
    }
}


//ClassC.cs
namespace CircularA {
    class ClassC : ClassB {
    }
}
like image 25
Alfred Myers Avatar answered Oct 28 '22 23:10

Alfred Myers