1

If I have an app that consists of multiple layers, defined as multiple projects in a solution, is it ok to have a layer reference the layer directly above/below it? Or, should one use dependency injection to eliminate this need?

I am building on a more specific questions that I asked here, but I would like more general advice.

How would I go about setting up a project like this in VS2010? Would I need a third project to house the DI stuff?(I am using Ninject)

EDIT: example

Here is an example of my two layers. first layer has an IUnitOfWork Interface and the second layer has a class that implements said interface. Setup in this manner, the project will not build unless layer 2 has a references to layer 1. How can I avoid this? Or, should I not even be worried about references and leave it alone since the layers are adjacent to one another?

Layer 1

public interface IUnitOfWork
{
    void Save();

}

Layer 2

 public DataContext : IUnitOfWork
 {
     public void Save()
     {
          SaveChanged(); //...
     }
 }
Community
  • 1
  • 1
stephen776
  • 9,134
  • 15
  • 74
  • 123

3 Answers3

1

General advise is to decouple layers by interfaces and use Dependency Injection and IoC containers for great level of flexibility whilst maintaining an Application. But sometimes it could be an overkill for small applications, so to give you a more specific example you have to provide at least description of the application and layers which it has.

Regarding DI stuff, I would suggest to encapsulate it in a separate assembly.

See great article by Martin Fowler Inversion of Control Containers and the Dependency Injection pattern

EDIT: Answer to comments regarding interface

Only one way to get rid of such coupling is to store common interfaces/classes in a separate assembly. In your case create separate assembly and put here is IUnitOfWork interface.

EDIT: Ninject projects reference

There are 147 Ninject projects, I would suggest to download and investigate most interesting from your point of view: Ninject projects

sll
  • 61,540
  • 22
  • 104
  • 156
  • Thanks for the response. I have read the Fowler article which is great. I guess my confusion stems from assuming that if one layer implements an interface from another layer, How can the solution build if I dont have a references from the implementation layer to the layer in which the interface resides? – stephen776 Sep 09 '11 at 11:46
  • 1
    Extract the interface in a separate assembly which will be referenced by all layers and use DI. – George Mamaladze Sep 09 '11 at 11:50
  • @stephen776 another good piece of reading concerning dependency injection and architecture is the onion architecture: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/ A real world implementation of the architecture can be found here: http://codecampserver.codeplex.com/ – rie819 Sep 09 '11 at 11:55
  • Thanks, that is pretty much what I needed to confirm. Does anyone have an examples of setting up such a project in visual studio with an IOC container? – stephen776 Sep 09 '11 at 12:18
  • @stephen776 : See second EDIT part of my answer – sll Sep 09 '11 at 12:35
1

This is a known "Tightly Coupled vs Loosely Coupled" dilemma and there is no general recommendation for it. It depends very much on how large are your component, how do they interact, how often are they changing, which teams do work on them, what are your build times.

My general advice would be keep balance. Do not go crazy by decoupling every mini class and on the other hand do not create a monolith where one small modification causes rebuild of the whole world.

  • Where change is expected, Favor loosely coupled components
  • Where stability is expected, Favor tightly coupled components

It is always a trade off:

There are costs associated with each decision:

The cost of having to make changes across tightly coupled components are well known. -The change is invasive -It may take a lot of work to determine everything in the dependency chain -It's easy to miss dependencies -It's difficult to insure quality

On the other hand, the costs of over-engineering are bad too -code bloat -complexity -slower development -difficult for new developers to become productive

To your example: Take a look at Stoplight Example coming along with Microsoft Unity Application Blocks enter image description here

George Mamaladze
  • 7,593
  • 2
  • 36
  • 52
  • Redesign as follows `IUnitOfWork` contains the data to be saved. `IUnitOfWorkLogic` - object which saves or does some other work on `IUnitOfWorkNotifier` - which makes calls. All of them declared in the same interface assembly. – George Mamaladze Sep 09 '11 at 12:01
0

People have already answered your question. I would suggest that the "below" layer should not reference the "above" layer as the below layer purpose is to provide certain functionality which is consumed by above layer and hence it should not know anything about above layer. Just like the nice layer model of TCP/IP stack

Ankur
  • 33,367
  • 2
  • 46
  • 72