In 2008, I coined a new pattern name called Onion Architecture. You can read the previous parts here: part 1, part 2, part 3. Over these four years, I’ve spoken about this pattern at user groups, conferences, and it’s even published in one of the chapters of ASP.NET MVC in Action from Manning.
I’ve been overwhelmed by the traction this pattern name has enjoyed. Folks from all over the country have written about and have talked about the pattern. Some of the ones I’ve noticed are here (please comment with more – I welcome it).
- Ayende Rahien’s opinion on Onion Architecture
- “Cunning” Clinton’s view
- Tony Sneed’s view and code sample
- StackOverflow questions on Onion Architecture
- Matt Hidinger’s Chicago .Net User Group video presentation on OA
- One interesting StackOverflow question.
Back in 2008, I defined four tenets of Onion Architecture:
- The application is built around an independent object model
- Inner layers define interfaces. Outer layers implement interfaces
- Direction of coupling is toward the center
- All application core code can be compiled and run separate from infrastructure
Although there has been significant adoption of this pattern, I have received countless questions about how to implement it in various environments. I mostly get asked about how it relates to domain-driven design. First, onion architecture works well with and without DDD patterns. It works well with CQRS, forms over data, and DDD. It is merely an architectural pattern where the core object model is represented in a way that does not accept dependencies on less stable code.
CodeCampServer was an original sample of onion architecture, but it also grew as a sample of how to do ASP.NET MVC in various ways, how to use Portable Areas, and how to use MvcContrib features like input builders. If you are just looking for onion architecture, it has too much going on. I have pushed a much simpler solution that represents onion architecture concepts. I have intentionally not included a UI input form or an IoC container, which most people associate with onion architecture. Onion architecture works just fine without the likes of StructureMap or Castle Windsor. Please check out the code here and let me know if this presents a simple approach – that is the goal.
When there is enough interest, I will continue this series with more parts. CQRS definitely deserves some addressing within this architecture, and so do object models that support task-based UIs.
Get the code here at my BitBucket repository.
Hey Jeffrey, quick question: in an Onion Architecture, where would you put cross-cutting concerns (logging, security, common utility functions, etc.)?
When deciding what to add to the core, you are making a judgement call about stability. By referencing System.dll, you are making a bet that this will be stable enough in the future to allow upgrading without too much hassle. It’s a pretty safe bet as long as .Net is around. If you add, or reference logging frameworks, security frameworks, or utility functions that in turn reference frameworks, you much make a judgement call about the stability of these as well. On a few projects, I have accepted Log4Net into the core because of its history of stability and small surface area. Data access libraries are a terrible bet in the core because they have a long-standing track record of being very unstable over time with new approaches coming out every 18 months. In face, just as Entity Framework comes on the scene, the NoSQL movement is currently jumping the chasm.
Everything is a judgement call, you can us similar techniques with security. Define the security operations in the core and then implement those interfaces in a library off to the side in an outer layer. For utility functions, I try not to have them. I try to find a nice same home (an object) that can own every utility function. If the utilities don’t use any other dependencies. If they are merely stack methods that only operate on the parameters passed to them, then there is no harm having them live in the core. After all, if they need no dependencies, then they are just as stable as the rest of the core.
Jeffrey,
Thanks for publishing this! I highly enjoy everything you write and speak. I look forward to many years of learning from you and hopefully working for you
-Justin Dial
Thanks Jaffery for wonderful architecture. I grabbed the sample source code from here : https://bitbucket.org/jeffreypalermo/onion-architecture/descendants, but where is the NIHibernateSample database there. I don’t find it being part of code repository. Could you please suggest where can I get that from?
Thanks
Deepak
See the nhibernate config…
You need to setup/create a database and point the config to it.
You can find the schema create script in the integration tests folder
Onion Architecture was mentioned just a few minutes ago by Steve Smith on his great talk “Common ASP.NET Design Patterns” over at aspconf.net.
Gotta say I love it. But just a little comment about your old posts on the matter: You can build layered architectures with interfaces too.
Just what I was looking for. Thanks
Hi Jeffery,
Great series, thanks for putting it together. I’ve been doing the Onion architecture for a while now without realizing it. I’ve actually been describing it as traditional N-Tier with contract layers inbetween the DAL and Application layers. I’ve also been using IoC to resolve dependencies for all the same motivations you called out. Once I realized that this was Onion and that you coined the phrase and documented the approach that was pretty exciting for me as we have worked together and I now have a living document that I can use to educate my teams.
Anyway, to my question. My biggest concern with this approach is that I feel that 3rd party data access technologies that use AOP (like NHibernate and Entity Framework) cause implicit coupling as they allow for behavior patterns that aren’t defined in the contracts (Domain Services). My concern is that this cause the abstraction to leak and causes coupling between infrastructure and sibling layers.
For example, if you are using NHibernate and you have a relationship modled between User and Role then in code you can do this:
User.Role
and Nhibernate will call the database for you to populate the role as part of it’s Lazy Loading implementation (EF does the same).
To me to be truely persistence ignorant then we should be able to change from NHibernate to anything, not just EF or other AOP database access frameworks. I think a more interesting scenario is when you have to switch from a database to a service. I’ve seen this happen a lot as shared databases get given to a dedicated team that moves to SOA. In that case you’d go from NHibernate to something like WCF.
One solution to this issue is to do things the harder way when it comes to your data access and not return mapped entities from your Domain Services. This does however have a productivity impact upstream as then you have to move to more of a services pattern on data access where you are no longer Lazy Loading related domain objects and instead sending in request configuration information that specifies what data to return (Request, Response pattern). This seems like a hard sell to clients who might not want to take a productivity hit for Persistence Ignorance. Another approach would be to attempt to implement an AOP wrapper for your WCF services but ouch, that seems expensive.
Have you encountered any approaches that help bridge the gap better than my proposed solutions above. If not then should part of the pattern be recomendation that you not allow AOP behaviors to leak across siblings by making your Domain Objects unmapped using something like the Entity Translator pattern? I guess that gets right back to my first proposed solution above. I’m stuck on that but looking for a better way.
In anycase I feel that this should be a part of the conversation for those seeking to provide the benifits of Persistence Ignorance using an Onion Architecture.
Ryan,
Good points. It is definitely possible to have implicit coupling where it is difficult to swap out a dependency. The way to tackle that is create smaller applications. Most of the time, an application can swap out a dependency. Where it becomes hard is when the app is really big. Taking the Fred Brooks guidance, by breaking up an app into several smaller apps that work together, we keep the whole simpler.
Jeffrey
Good to know about Onion Architecture but how will we handle in clustering technologies , I mean pros and cons using it in Clustered environment
This is a great starting point, thanks for putting it together. I am a little concerned with the Repository implementation automatically committing the Session though. I think that’s great for a small CRUD-derived app, but doesn’t mesh as well with larger projects, which you’ve stated is the intended use case for Onion Architecture. I’d like to see a reference implementation where the app needs to coordinate several repositories in order to solve some problem.
Thanks a lot for all of your work. Somebody probably already said this, but a CQRS approach related to this architecture would be very helpful and interesting. In particular if it follows the same approach as your pared-down example of onion architecture without UIs, IoC containers and so on.
I really have to try this onion!
Could any one please answer my question on Stackoverflow “Does Onion Architecture contradict IoC”
http://stackoverflow.com/questions/15134530/does-onion-architecture-contradict-ioc
Thanks for your insight. It inspired me and I mentioned it in one of my series (http://ludwigstuyck.wordpress.com/2013/03/05/a-reference-architecture-part-1).