views:

128

answers:

3

In theory in layered architecture you can have multiple modules on the same layer. Can this modules cross reference to each other? Is is possible technically, eg. using .NET?

+1  A: 

It is certainly possible to do so, just be careful not to introduce any cyclic dependencies between modules. In general, modules at a given layer should only depend on other modules from the same layer or from the layers below it. Modules should not be aware of the layers above them.

If you want to make this even stricter, then you can also limit dependencies to other modules from the same or other layers immediately below the current one.

Keeping the exposed interface to a minimum, e.g. exposing only a core set of public interfaces, value objects, and exceptions is always a good idea. You can use the language's access control features (i.e. private/package/public) to limit visibility of module internals from spilling into other layers.

Pavel
A: 

Technically you can cross-reference in any direction you want in .NET (there are not technical limitations for a DAL to reference a UI component, even though it may not be a good idea). I see no problems with referencing modules within the same layer.

But we need to look at the word "layer" a bit, since layers come in different shapes and sizes. Often when we use the word "layer" we think Data Access Layer or Presentation Layer, and we typically allow layers look downwards but not upwars.

Within each layer, the different modules often also let themselves be arranged into layers, logically. The same rule applies here; a module can look down but not up. With that in mind it it feels rather safe to reference modules within the same (outer) layer.

Just don't have two modules reference each other, directly or indirectly. If you find that A and B both need functionality from each other (indicating that A and B are on the same level), you will probably need to refactor the code, perhaps introducing a new module C, logically placed below A and B that both of them can use.

Also keep in mind to keep the modules as detached as possible; the less they know about each other, the better.

Fredrik Mörk
you say "Technically you can cross-reference in any direction you want in .NET", but when most people talk 'layers' they imply 'assemblies' also, and this becomes a problem.
Luke Schafer
@Luke: that's what I mean; you can reference any assembly you like, VS has no clue about which "layer" it belongs to. You can reference your WinForms UI assembly from the DAL assembly, but it's not a good idea. Also, I am not so sure about the connection between layer and assembly; I don't think I have been involved in any project where a layer consisted of one assembly only. But we all have different perspectives, so you may be right.
Fredrik Mörk
A: 

as Pavel said, be careful with your cyclic dependencies. If you absolutely can't live without a cyclic dependency (what you call cross reference), the classes must be not only from the same 'layer', but also the same assembly.

That being said, there should be no reason for cross referencing - not only should (as pavel said) modules only depend on the layers below them, that one-way-dependency should exist in all cases.

There are some logical exceptions to this rule, for example in something like a domain model - a customer will have a number of orders, say. It might be useful in that case (esp with ORMs etc) to have a list of orders on the customer, and a reference to the customer from each order. In terms of units of functionality like services etc, there should only be one way dependencies.

One way to get around this issue is to use Inversion of Control through Windsor, autofac, spring.net etc. You can define an interface in an assembly and another object that consumes a concrete implementation of that interface. Another library might contain the actual implementation (meaning that assembly must reference the first assembly). In this case, the IoC container grabs the implementation.

Luke Schafer