Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Revisiting the onion

I’m working on a chapter on layering for the upcoming Brownfield book, and for better or for worse, we’re including a section on the onion architecture. I’ve heard the term mentioned for some time now but for the life of me, I can find only one meaty series of posts on it in recent months. That one caused a bit of a kerfuffle but the ado was big enough that I said to myself, "hillbilly, you don’t want to be treadin’ into dem waters anytime soon." But I need some excuse to do some extemporizin’ and I’m hoping this will help crystallize things in my head.

I’ll start with my own version of the diagram because I spent enough &*%$ time on the thing. Wanna get some mileage out of it.

image

Jeff’s explained it pretty well, I think. It’s clear that the Domain is at the centre and thus, is the focus of the application. I’ve skipped the Domain Service layer for two reasons:

  • It should be part of the Domain layer
  • There’s a good chance that your domain services should really be methods on your domain objects. (e.g. FundsTransferService should really be a TransferFundsTo method on the Account object)

So here’s where my take comes in. I don’t like the onion metaphor, or the diagram a whole lot. For someone coming at it from a traditional n-tier approach, it’s confusing. It looks to me like the UI talks to Application Services, which talks to the Domain. That is, it’s not obvious that the outside layers can talk to any inside layer without some fancy footnotin’.

The problem I think is with the term "layer". It implies a level of insulation. That is, the Domain looks like it is insulated from the UI and Infrastructure by the Application Services layer. Which isn’t the case by any stretch.

Next issue is that the diagram does *not* make clear what was a hard concept for me to understand initially. Namely, that the interfaces for the repositories live in the domain but the implementations in the infrastructure. And it’s done without the UI referencing the infrastructure layer (usually with an IoC container).

Then there’s the whole UI segment abutting against the infrastructure which is kinda wacky. Can the UI talk to the Infrastructure? Does the Infrastructure even use the Application Services? In my experience, not really. It interacts directly with the Domain.

Which brings up another issue. How does the use of DTOs affect this diagram? I’m on the fence about this, but I’ve seen cases where the UI doesn’t ever use domain objects. The objects are translated into DTOs by the Application Services. So the UI "layer" doesn’t technically have access to the Domain "layer".

Having said that, I don’t know if I could come up with a better diagram. As it is, I don’t know if I could even properly define "Application Services". All I know is that, for someone relatively new to this, an analogy should not need three posts to explain it.

When Jeff’s posts came up, I read them with interest and they jibed with my understanding of onions in general, so I moved on. The metaphor seemed natural but I admit, I didn’t look into its meaning too much. Hillbillies aren’t a naturally metaphorical species.

Now I’m having to dive into it a little more and I find myself wondering if it will do more harm than good. To the inexperienced, it looks like a vastly different take on the traditional n-tier diagram. And on more than one occasion, it occurred to me that they aren’t really that different. To oversimplify, you could just substitute the domain layer for the business logic layer, change the direction of some arrows, and have a passable draft of it.

On the other hand, this line of thinking does *not* bode well for me finishing chapter 8 this weekend.

Kyle the Indecisive

This entry was posted in Brownfield. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • roberto diana

    HI

    image schema is missing

  • http://shapingsoftware.com J.D. Meier

    I agree — I think the diagram and metaphor aren’t idea.

    We have some relevant work in progress you may be interested in:
    * Layers and Tiers – http://blogs.msdn.com/jmeier/archive/2008/09/06/layers-and-tiers.aspx
    * Layers and Components – http://blogs.msdn.com/jmeier/archive/2008/09/07/layers-and-components.aspx
    * Services Layer – http://blogs.msdn.com/jmeier/archive/2008/09/07/services-layer.aspx

  • Kyle Baley

    @Joseph Not entirely sure what you mean but I’ll continue with some assumptions.

    Firstly, what I have is simply a version of Jeff’s diagram. I make no claim as to origins to either the diagram or the concept. Secondly, I’m pretty sure this diagram ignores tiers altogether. It’s conceptual/logical in nature. A tier (assuming you mean a physical tier) would consist of many layers.

    And in that sense, yes, they’d be part of the same tier. But I don’t consider the domain services as a layer on top of the domain. The domain contains some logic in it. I’d move to a domain service only in complex cases that don’t fit within the context of a single domain object. As such, I consider domain services as the same level as the domain classes.

    And when I say “I consider”, that’s not based on a whole lot of practical application yet. Mostly me sitting around having a good think about it like Winnie the Pooh does about his problems.

  • http://swcses.eponym.com/blog Joseph Reddy

    Are you missing the conceptual differnce between tires and layers in your diagram? In this sense, I mean that the Domain Service and Class layers are in the same tier.

  • Kyle Baley

    @Fregas

    Actually, you bring up a point I wrestled with. It is, as you say, very different than the layering that is often discussed in the Microsoft world. But I don’t believe that was even a valid architecture to begin with. Combining persistence and business logic violates even Microsoft’s own line of separating business logic and data access.

    I was comparing it more with how I would do a traditional n-tier architecture where a request passes from the UI to a business layer which may do some validation, then send the data to the data access layer to save to the database.

    Compared that to a call where an object passes from the UI to an application services layer which translates it into a full-fledged domain object. Then it calls another layer to retrieve a repository from the data access layer. Whether that layer is explicit (as in a Factory or a Service Locator) or implicit (via an IoC container), it’s still a layer, I think.

    So really, we’re retrieving a hybrid data access/domain object in our application services to do the persistence for us. It’s not altogether removed from the traditional model where the domain model and business logic layer are combined. Yes, there are differences but I don’t know if they are enough to warrant such a radically different metaphor.

  • http://www.dotnettricks.com Fregas

    Hi Kyle,

    Having taken Jefferey’s Agile Bootcamp class, I can say that this is (to me) very different from traditional layering at least as discussed in the Microsoft world. Traditionally, you have UI talking to a Business layer which talks to a data layer. Microsoft and others tend to encourage the use of “manager classes” which do both persistance and business logic against a anemic domain objects that do very little if any logic of their own.

    Onion architecture flips this around quite a bit. Whether the onion metaphor or the diagram expresses this clearly enough for newbies I can’t say. But it seems that they are very different approaches.

  • Kyle Baley

    @Jimmy: Yes, I believe that is why it is so popular. It’s very clear that the domain is the important piece. But I still think the rest of it has enough issues that an alternative should be considered.

    @Colin: Yeah, that was a big misstep on my part which Donald Belcham pointed out to me in our conversation afterward. Domain Services are still very much needed but I don’t like how the diagram indicates they are another layer over the domain. They should be considered as the same level. That is, you don’t have a domain object, then a domain service that uses the object. Rather, you have domain objects and domain services together. In harmony. Singing together and buying the world a coke, etc, etc, and so on and so forth.

    By way of an update, we agreed to scrap the onion metaphor for the layering chapter and instead have a section on refactoring using a domain-centric approach to layering. Same idea but without an analogy we’d have trouble defending.

  • http://colinjack.blogspot.com Colin Jack

    Good point, and as you say since there is no strict layering the diagram could be confusing especially without either adding arrows showing how communication flows or copious amounts of caveats.

    “(e.g. FundsTransferService should really be a TransferFundsTo method on the Account object)”

    I’m not sure thats always true, in fact isn’t that one of the examples that Evans discusses in the book? Even with a good domain model I think domain services have their place, especially when coordinating cross aggregate beahvior.

  • http://jimmybogard.lostechies.com Jimmy Bogard

    As metaphors go, it’s a nice first step. Taking it too far has its issues. What I liked is that it illustrates where the meat of the application is: the domain.