The Onion Architecture : part 2

part 1. This is part 2. part 3. part 4My feed (rss).

In part 1, I introduced an architectural pattern that I have named "Onion Architecture".  The object-oriented design concepts are not new, but I'm pulling together a lot of techniques and conventions into a single pattern and giving it a name.  My hope is that the industry can use this name to communicate the architectural approach where appropriate.

Part 2:  Practical example:

CodeCampServer uses the Onion Architecture.  If you are looking for a full, working application as an example, please have a look.  The practical example I put before you is taken directly from CodeCampServer.  It is a narrow, vertical slice of an example.  I'm keeping the scope small as to be digestible.  I'll start with a diagram so you can understand where all the code resides within the layers of the onion. 

CodeCampServer uses the ASP.NET MVC Framework, so SpeakerController is part of the user interface.  This controller is coupled to the ASP.NET MVC Framework, and there is no getting around that.  SpeakerController depends on IConferenceRepository and IUserSession (and IClock, but we'll omit that).  The controller only depends on interfaces, which are defined in the application core.  Remember that all dependencies are toward the center

Turn your attention to the ConferenceRepository and UserSession classes.  Notice that they are in layers outside of the application core, and they depend on the interfaces as well, so that they can implement them.  These two classes each implement an interface closer to the center than itself.  At runtime, our Inversion of Control container will look at its registry and construct the proper classes to satisfy the constructor dependencies of SpeakerController, which is the following:

public SpeakerController(IConferenceRepository conferenceRepository,
                         IUserSession userSession, IClock clock)
    : base(userSession)
{
    _conferenceRepository = conferenceRepository;
    _clock = clock;
    _userSession = userSession;
}

At runtime, the IoC container will resolve the classes that implement interfaces and pass them into the SpeakerController constructor.  At this point in time, the SpeakerController can do its job. 

Based on the rules of the Onion Architecture, the SpeakerController _could_ use UserSession directly since it's in the same layer, but it cannot use ConferenceRepository directly.  It must rely on something external passing in an instance of IConferenceRepository.  This pattern is used throughout, and the IoC container makes this process seamless.

At the end of this series, I plan on publishing a full working system that adheres to the Onion Architecture pattern.  The systems we build for clients use this approach, but I'm not at liberty to discuss that code, so I will craft a reference application for those of you who prefer a concrete Visual Studio solution to digest.


Trackbacks

The Onion Architecture : part 1 : Jeffrey Palermo (.com) Posted on 7.30.2008 at 8:18 AM

Pingback from The Onion Architecture : part 1 : Jeffrey Palermo (.com)

The Onion Architecture : part 2 Posted on 7.30.2008 at 8:50 AM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Reflective Perspective - Chris Alcock » The Morning Brew #148 Posted on 7.31.2008 at 2:31 AM

Pingback from Reflective Perspective - Chris Alcock » The Morning Brew #148

Dew Drop - July 31, 2008 | Alvin Ashcraft's Morning Dew Posted on 7.31.2008 at 9:38 AM

Pingback from Dew Drop - July 31, 2008 | Alvin Ashcraft's Morning Dew

So you want to learn NHibernate - Part 1/2, Prerequisites (or NHibernate = Marijuana.NET) « HSI Developer Blog Posted on 7.31.2008 at 12:53 PM

Pingback from So you want to learn NHibernate - Part 1/2, Prerequisites (or NHibernate = Marijuana.NET) « HSI Developer Blog

Links of the Week August 2 2008 Posted on 8.01.2008 at 8:10 PM

Another week of great resources for the .NET developer to take in. Amazing how many are out there. I

Weekly Links #12 | GrantPalin.com Posted on 8.03.2008 at 9:07 PM

Pingback from Weekly Links #12 | GrantPalin.com

The Onion Architecture : part 3 Posted on 8.04.2008 at 9:34 AM

Part 1 - Part 2 - This is part 3 - My RSS feed In my previous installments, I described what has become my approach to defining the architecture for an application. Based on feedback, I've modified my diagrams a bit to reduce ambiguity and emphasize key

Weekly Web Nuggets #23 Posted on 8.04.2008 at 9:36 AM

General The Onion Architecture Part 1 : Jeffrey Palermo proposes a new architectural pattern that is based on how components are coupled to each other. The Onion Architecture Part 2 : Jeffrey Palermo continues his presentation of the Onion Architecture

So you want to learn NHibernate - Part 0.5, Prerequisites (or NHibernate = Marijuana.NET) | The Freak Parade Posted on 8.08.2008 at 5:39 PM

Pingback from So you want to learn NHibernate - Part 0.5, Prerequisites (or NHibernate = Marijuana.NET) | The Freak Parade

Training module - Layering Posted on 8.15.2008 at 1:48 PM

Training module - Layering

The Onion Architecture | Dev @ Work Posted on 8.26.2008 at 12:43 PM

Pingback from The Onion Architecture | Dev @ Work

Comments

Torkel said on 7.30.2008 at 8:54 AM

Great post again, I think what you are doing is a very good idea. The principle of inversion of control can fundamentally change how applications are layered, and it is a good idea to have a name for this architectural pattern.

David Carrillo said on 7.30.2008 at 9:43 AM

CodecampServer is not working for me

Paul said on 7.30.2008 at 12:44 PM

Thanks for taking the time to fully explain this architecture. I'm looking forward to sharing this with my coworkers to help them understand why I prefer this architecture

Greg Young said on 7.30.2008 at 12:48 PM

OK In domain services you put an example of on being "IConferenceRepository" ... please oh please don't overload the concept of what a domain service is any more ... It's already difficult enough to explain to someone which of the 22 definitions actually apply.

OtherPeter said on 7.30.2008 at 2:32 PM

Greg, can entities depend on domain services?

Love It... said on 7.31.2008 at 6:58 AM

So, this is exactly how I (try to) go about designing my applications. One question though: In a web scenario, how would you go about handling Response.Redirects? you can mock out IHttpContext, but... Ideas?

Jeffrey Palermo said on 7.31.2008 at 7:52 AM

@Greg,

This post isn't meant to be about domain-driven design, and, like you mentioned, there are many different definitions. The industry hasn't been able to agree on the exact details of a definition, so I don't presume to expect that here. Thanks for the comment. I really appreciate your feedback.

Jeffrey Palermo said on 7.31.2008 at 7:56 AM

@Love It,

Response.Redirects are a detail of the UI you are using. Navigation is an application context. You have to assign the responsibility of navigation somewhere. Is is a concept you discuss with your domain experts or is it there just because you have a web application instead of a console application? I typically handle it by having a IRedirector interface in the UI layer, and my UI controllers make use of this interface.

Raj Moodaley said on 8.01.2008 at 4:33 PM

Looking forward to the next installment. Many thanks