Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
Hi,
 
We are bombarded by advice always to program to an interface, rather than an implementation, to reduce dependencies. I can see the benefits of this, and within an individual project, I use this technique to decouple classes wherever appropriate. But, what happens when you want to decouple two separate projects?
 
Imagine you have two separate libraries, LibA and LibB. You don't want either library to 'know' about the other, but, when you use them in a client application, you want LibA to be able to call a function in LibB. When I came across this problem, I thought, 'Oh, I'll use an interface,' but then I came upon the problem of where to define this.
 
If I put it in LibA, then, for LibB to be able to implement it, it becomes dependent upon LibA. The client application could define it, but then I would have to do a copy-paste of the code into any other applications that needed the same functionality.
 
There is a third option - creating the interface in a separate project/assembly of its own. This does the job, but seems like using a hammer to crack a nut.
 
Can anyone offer any advice on this? Am I stuck in the wrong mode of thinking? Should I be looking at something completely different? All advice gratefully received.
 
Kind wishes ~ Patrick
Posted 28-Mar-13 10:44am
Comments
Sergey Alexandrovich Kryukov at 28-Mar-13 15:56pm
   
What do you mean by "We are bombarded by advice always to program to an interface, rather than an implementation"? What would be the sense in it? Who told you so?
—SA
Patrick Skelton at 30-Mar-13 5:48am
   
Hi,
 
I have several books on software design and patterns and the phrase 'program to interfaces' or something similar pops up again and again. I am aware that - sooner or later - you have to implement an interface, and - as with all guidelines - there are times when it isn't the best choice, but it does generally seem to improve decoupling.
 
- Patrick
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Please see my comment to the question; the statement is not clear…
 
First of all, I hope that by LibA and LibB you mean the assemblies. Actually, every .NET assembly is a library, even if it is named *.EXE (in case you still did not get it); and there are cases when even *.EXE should be a referenced assembly. (This is not a very usual technique, but it is quite legitimate; I can explain why it can be used if you are really curious, but this topic is unrelated to the question.)
 
Then, you need to understand that there is no such thing as a miracle. If you use some interface, either for implementing it of for using objects by interface reference, you need to have it defined. It can be defined in your using assembly or in any referenced assembly. Of course, if two interfaces are textually identical but are defined in different assemblies, there are different interfaces and cannot be used interchangeably; besides, such definitions would violate the very fundamental DRY principle (http://en.wikipedia.org/wiki/Don%27t_repeat_yourself[^]); so, let's forget such cases and assume that there is only one definition of each interface. By the way, loading assemblies dynamically during runtime changes the character of dependencies but not the facts stated above. This is all you need to know at the moment.
 
Now, let's follow the simple logic. Imaging you have some interface IMy used by both your assemblies. It means that is should be defined somewhere. Defining it in LibA will make LibB dependent of LibA and visa versa, as you correctly pointed out. In many cases, you really need this dependency. It all depends on the semantic of the assemblies. And yes, there are cases when none of these two assemblies should depend on the other one. In this case, applying the same principle "there is no such thing as a miracle", we come to the only remaining solution: IMy should be defined in another assembly, say, "Interfaces", and then both LibA and LibB assemblies should reference it. As simple as that.
 
I must note that all the logic is applicable to absolutely any kind of definition; there is nothing specific to interfaces. That said, you might miss the role of interfaces in the architecture of the code and the dependencies. You should do the following: think of interfaces, their implementation and uses without any concern about assemblies.
As to dependencies, please review these design patterns:
http://en.wikipedia.org/wiki/Dependency_injection[^],
http://en.wikipedia.org/wiki/Dependency_inversion_principle[^].
 
A really productive way of making the architecture is thinking on the dependencies of .NET types first, and when the picture is more or less clear, think about distribution of the code into different assemblies. Well, as a rule of thumb. This is because the dependencies between assemblies is the product of dependency relationships between type, not visa versa, and because the boundaries between .NET assemblies are very light-weight, from the standpoint of development process. In other words, if you move some code from one assembly to another, with corresponding removal and adding of the assembly references, it won't change the using and depending code even a bit.
 
—SA
  Permalink  
v2
Comments
Maciej Los at 28-Mar-13 16:55pm
   
VVVIA - Very, Very, Very Interesting Answer!
+5
Sergey Alexandrovich Kryukov at 28-Mar-13 16:57pm
   
Thank you, Maciej.
—SA
Patrick Skelton at 30-Mar-13 6:02am
   
Thank you for that detailed reply. It has helped me a lot to think about this problem.
 
Sorry I wasn't clear in my original question about what I meant by libraries and assemblies.
 
Kind wishes, Patrick
Sergey Alexandrovich Kryukov at 30-Mar-13 21:18pm
   
You are welcome. (And there is no need to apologize; there is nothing wrong about calling you assemblies libraries, as this is what you want them to be; my notes just to help to generalize the notion.)
So, will you accept the answer formally then (green button)? — thanks.
—SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

With Visual Studio? You can define the interface in its own file (perhaps in one of the projects) then use "Add | Existing... | As link" to add it to any other projects that need it.
  Permalink  
Comments
Sergey Alexandrovich Kryukov at 28-Mar-13 16:31pm
   
The question is not related to IDE, and not to dependency between files of the project (which is trivial), but to dependency between assemblies, which OP calls "libraries", which in fact they are.
Please see my answer.
—SA
PIEBALDconsult at 28-Mar-13 19:25pm
   
Your answer is too long. :D
Sergey Alexandrovich Kryukov at 28-Mar-13 19:27pm
   
Sorry, did not want to get your that bored... :-)
Thank you,
—SA
Patrick Skelton at 30-Mar-13 5:51am
   
Thanks for the comment about adding links. Having a spurious file hanging about that is not a part of a project/assembly doesn't 'feel' right to me.
 
- Patrick
PIEBALDconsult at 30-Mar-13 11:08am
   
It wouldn't be; it would be a member of both projects. However, upon further reflection, it doesn't seem to be what you want for the situation you describe.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 587
1 Sergey Alexandrovich Kryukov 544
2 Maciej Los 325
3 DamithSL 223
4 Mathew Soji 195
0 OriginalGriff 7,356
1 Sergey Alexandrovich Kryukov 6,712
2 DamithSL 5,461
3 Manas Bhardwaj 4,916
4 Maciej Los 4,475


Advertise | Privacy | Mobile
Web03 | 2.8.1411023.1 | Last Updated 28 Mar 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100