Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cyclic dependencies - yet again

Tags:

c#

.net

I am struggling with avoiding cyclic dependencies. I know I need to hide the implementation with interfaces, but how do I handle a situation with two assemblies, where each either needs to instantiate classes from the other or call a static method from there?

Edit:

I understand this can be fixed by using just a single assembly. We have more than one for the following reason:

  • our "system" consists of several components. A customer can have just one component, or more - so what we did is we created different assemblies for different components. It kind of makes sense - why would you deploy things that you do not need - is it not a wasting of memory?
  • things that were common to more components, mostly helper classes, went to another assembly - again not all components need all helper classes, so there are more assemblies
  • however, these two applications can talk to each other - the system for doctors sends requests to the system for nurses, requests are going back, etc. - and here's where the actual problem is

Having the two components talking to each other is really just one of the situations we've had a cyclic dependency conflicts before. It happens now and then and when it happens we need to figure out how to solve it - move some classes around - and sometimes we need to add a new assembly.

Now we have like 8-10 assemblies, and it looks like the more you have the faster they get added :) - for example, we added a general purpose feature that uses custom attributes - so we added another assembly just for the attribute - just in case we do not get in conflict in future

Is this the way to go? I am really feeling we are doing something fundamentally wrong :)

I really appreciate your input.

like image 765
Martin Haluza Avatar asked Jan 12 '10 19:01

Martin Haluza


People also ask

How do you fix cyclic dependency?

There are a couple of options to get rid of circular dependencies. For a longer chain, A -> B -> C -> D -> A , if one of the references is removed (for instance, the D -> A reference), the cyclic reference pattern is broken, as well. For simpler patterns, such as A -> B -> A , refactoring may be necessary.

How do I fix circular dependency in react?

This circular relationship caused a problem and webpack could not resolve the dependencies correctly. Our solution was to upgrade our modules to use ES6 import/exports. This enabled us to reuse the react components and avoid circular dependencies while moving us closer to ES standards.

How do I get rid of cyclic dependency in Java?

A simple way to break the cycle is by telling Spring to initialize one of the beans lazily. So, instead of fully initializing the bean, it will create a proxy to inject it into the other bean. The injected bean will only be fully created when it's first needed.

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.


1 Answers

I would try to pull the offending types out into a third 'common' assembly that the two 'parent' assemblies reference.

I would question why you need multiple assemblies in the first place, however, when they both depend on each other. Assemblies are units of deployment, and can be versioned separately from each other. If you don't need this functionality, I would just package everything into a single assembly and be done with it. This has the added bonuses of speeding up the build and simplifying deployment.

Please do try to add more context to your question - maybe there are some details we can help with if we know exactly what it is you're trying to do.

Edit re your additions: To specifically answer your question regarding whether or not multiple assemblies is the way to go, consider this: I once worked on a codebase like this with Visual Studio 2008, where there were about 20 separate project files open in the solution at once. These 20 projects were all supporting DLLs for a single main EXE. These projects were not shared with other products, nor were there strange versioning requirements.

Working with this solution was a nightmare. It took literally 5 minutes for Visual Studio to compile the solution. Compiling in the command line with MSBuild took 2 minutes. This made making incremental changes an exercise in frustration and pain. Since all of the projects were used in the making of the main executable, none of them could be unloaded to speed up the compile, and there was an executive mandate against breaking projects out into separate solutions.

If you end up with a single solution like this, trust me when I say that you and your teammates will revolt one day... My recommendation would be to break out assemblies into their own solutions, grouping together any assemblies that are likely to be changed together; then create a custom build task that copies the final assembly into a common folder from which all the other assemblies can take references.

like image 59
Erik Forbes Avatar answered Sep 16 '22 19:09

Erik Forbes