Click here to Skip to main content
15,880,543 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
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
Comments
Sergey Alexandrovich Kryukov 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 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

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
 
Share this answer
 
v2
Comments
Maciej Los 28-Mar-13 16:55pm    
VVVIA - Very, Very, Very Interesting Answer!
+5
Sergey Alexandrovich Kryukov 28-Mar-13 16:57pm    
Thank you, Maciej.
—SA
Patrick Skelton 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 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
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.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 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 28-Mar-13 19:25pm    
Your answer is too long. :D
Sergey Alexandrovich Kryukov 28-Mar-13 19:27pm    
Sorry, did not want to get your that bored... :-)
Thank you,
—SA
Patrick Skelton 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 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)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900