Pergunta

I am trying to refactor the system according to Onion Architecture approach.

My outer layer includes the following segments

  1. WCF web service (which we provide)

  2. infrastructure classes for DB access

  3. infrastructure classes to access external web services

  4. tests

I'd like to double check if different segments of the outer layer are allowed to have dependencies on each other. For example, can WCF classes directly depend on any code from infrastructure assemblies?

As far as I understand it is not allowed. E.g WCF code should only depend on code (eg interfaces) from the inner layers. Could you please confirm it?

PS

I am a bit confused because on one hand some articles confirm it:

http://blog.ploeh.dk/2013/12/03/layers-onions-ports-adapters-its-all-the-same/

You have probably noticed that I've grouped the orange, yellow, and blue boxes into separate clusters. This is because I still want to apply the old rule that UI components must not depend on Data Access components, and vice versa. Therefore, I introduce bulkheads between these groups

but on the other hand the tests (eg for code in the infrastructure assemblies) sit in the same layer as the infrastructure assemblies and have direct dependency on them.

Foi útil?

Solução

Talking in terms of physical assemblies, infrastructure assemblies (assemblies which contain code that addresses a problem [usually] utilizing a specific framework) shouldn't reference each other directly. Instead you should aim to (at least in my experience) extract an interface from those assemblies and place them into a separate assembly which other infrastructure assemblies can reference. Using your (approximate) situation as an example, you could do something like this:

Example Onion Architecture

Things to note:

  • All of the boxes represent actual assemblies (projects in Visual Studio).
  • Green boxes represent interface assemblies, whereas red boxes represent infrastructure assemblies.
  • Interface assemblies contain abstract classes, interfaces, constants etc. They provide abstractions for infrastructure assemblies to use.
  • Infrastructure assemblies contain framework-specific code and implement the abstractions contained in the referenced interface assemblies.
  • The bootstrapper isn't necessarily required, you can just put the initialization logic in your Global.asax.
  • During the WCF Service's starup process, Dependency Resolution is invoked which registers type mappings.
  • Each assembly has their own test assembly (if required).
  • This design prevents circular references between assemblies "in the same layer".
  • You can easily replace Google Maps with Bing Maps and Entity Framework with NHibernate. The only references that change are in Dependency Resolution.

Let me know if you need further information.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top