开发者

Cyclic dependencies - yet again

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 adde开发者_开发问答d 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.


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.


Can you put the common stuff in its own assembly?

I agree with one commenter that we probably need more information.

Why do you have 2 assemblies?

Is there a reason everything's not in one assembly?

How are these assemblies connected? Just via reference or are there WCF, etc components involved?

We've given you the simplest answers, but maybe there's more to it than we can tell by your brief description.


One way to avoid it would be using a proxy / business structure.

AssemblyA.Proxy - contains two classes: one interface (let's call it IServices), and another class responsible for calling AssemblyA.Business methods.

AssemblyA.Business - contains one class, which implements the methods declared on IServices.

AssemblyB.Proxy - analogue to AssemblyA.Proxy

AssemblyB.Business - analogue to AssemblyA.Business

This way, each Proxy component would reference only the business logic they're supposed to. AssemblyA.Proxy would have a reference to AssemblyA.Business; AssemblyB.Proxy would have a reference to AssemblyB.Business. AssemblyA.Business would reference AssemblyB.Proxy, and so on.

Don't know if it it's clear but hope it helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜