Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to enable circular dependencies in Visual Studio at the assembly level? Would mutually dependent assemblies even be possible?

This probably sounds like a stupid question, but I'm going to give it a shot anyway.

So in Visual Studio, you can't have two projects X and Y such that X references Y and Y references X.

In general, I can totally understand how having a circular dependency can be problematic, for a variety of reasons.

But is it really not possible to compile two projects that are interdependent in this way? It seems to me that it must be possible, since (in my mind -- maybe I'm completely off-base about this) having two mutually dependent assemblies is really not so different from having two mutually dependent classes -- a case which is legal and can be compiled.

It would make sense to me if you said, "two assemblies cannot depend on each other because the compiler could not compile one before the other"; except that it seems you could make the same argument for two classes within the same assembly, and clearly the compiler can deal with this scenario just fine.

Basically the reason I'm asking is not that I have some desperate desire to do this thing that I know is generally ill-advised anyway. Specifically I'm wondering because it would be nice if I could have two projects -- say, MyProjectCS and MyProjectVB -- that existed basically as two mutually dependent parts of a single unit, and were only separate because certain parts were written in C# and other parts were written in VB.NET.

So, my question is (yikes, three-fold):

  1. Is it possible to enable this behavior (in Visual Studio, or elsewhere, for that matter)?
  2. If it's not possible within any IDE, is it at least theoretically possible, or could mutually dependent assemblies not possibly exist?
  3. If it's not even theoretically possible, why not? In other words, how are mutually dependent assemblies different from mutually dependent code within a single assembly?
like image 763
Dan Tao Avatar asked Jul 03 '10 01:07

Dan Tao


People also ask

Is circular dependencies possible in spring boot?

It can happen in Spring when using constructor injection. If we use other types of injections, we shouldn't have this problem since the dependencies will be injected when they are needed and not on the context loading.

Where can we face the problem of circular dependency and which approach can resolve it?

Circular dependency problem can be overcome by using interfaces or events. So for the above problem, we can introduce an interface in between the “ MiddleTier ” and “ Dal ”. This interface project you will implement in the middle layer project on the “ Customer ” class.

What are circular dependencies among servers and how can they be avoided?

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's wrong with circular dependencies?

Circular dependencies also make code difficult to read and maintain over time, which opens the door to error-prone applications that are difficult to test. If circular dependencies proliferate an architecture, any changes to a single module will likely cause a large ripple effect of errors for others.


2 Answers

I don't know how to do it in an IDE; however it is possible to construct via a compilicated build process.

You will need:

  1. Assembly A
  2. Assembly B
  3. Stub Assembly B

where Stub Assembly B contains the public classes and public methods of Assembly B and the same AssemblyInfo.* and references the same public key.

Build order:

  1. Compile Stub Assembly B
  2. Copy Stub Assembly B to the output dir of Assembly B
  3. Build assembly A
  4. Build assembly B

Notice that you cannot have direct loop references of the types in the method signatures; however you can have effective loops by casting through object.

NOTE:

ilasm can compile true mutually recursive assemblies as somehow it can resolve types that don't exist at compile time.

FURTHER:

the aspnet_compiler seems to be able to mix different languages in the same project (who knows how).

like image 90
Joshua Avatar answered Sep 29 '22 19:09

Joshua


Even though mscorlib.dll and System.dll assemblies are mutually dependent, I'd advise to never have 2 assemblies mutually dependent.

Concerning dependency cycles between hings like namespaces, I'd advise using NDepend to detect and avoid dependency cycles.

alt text

Excerpt from the article (I wrote): Control component dependencies to gain clean architecture

Dependency cycles between components lead to what is commonly called spaghetti code or tangled code. If component A depends on B that depends on C that depends on A, the component A can’t be developed and tested independently of B and C. A, B and C form an indivisible unit, a kind of super-component. This super-component has a higher cost than the sum of the cost over A, B and C because of the diseconomy of scale phenomenon (well documented in Software Estimation: Demystifying the Black Art by Steve McConnell). Basically, this holds that the cost of developing an indivisible piece of code increases exponentially.

This suggests that developing and maintaining 1,000 LOC (Lines Of Code) will likely cost three or four times more than developing and maintaining 500 LOC, unless it can be split in two independent lumps of 500 LOC each. Hence the comparison with spaghetti that describes tangled code that can’t be maintained. In order to rationalize architecture, one must ensure that there are no dependency cycles between components, but also check that the size of each component is acceptable (500 to 1000 LOC).

like image 32
Patrick from NDepend team Avatar answered Sep 29 '22 18:09

Patrick from NDepend team