Onion Architecture – C#.NET

By | December 29, 2012

If you never heard about the “Onion Architecture”, you should read Jeffrey Palermos blog post. He’s the Onion-Architecture-Guru ๐Ÿ˜‰

I created a very small demo VS.NET solution, which shows how I would apply this type of architecture in a project. (The download link is at the bottom of this post.)

The following graph displays the dependencies between the VS.NET projects.

OnArch Dependency Graph

OnArch Dependency Graph


My Core contains two libraries:

OnArch.Core Is the main core library and contains the business logic and the interfaces for all outer layers. This project doesn’t contain any references to technology specific assemblies like EF etc.
OnArch.Core.Entity Contains only the entities. It’s allowed to place entity-specific logic inside the entity classes. But I would prefer to place all logic in the OnArch.Core project. The reason why I placed the entities in a separated project is: Sometimes you may need only the entities and not the whole application logic etc. For example, when you have a WCF service and a .NET WCF client and you don’t want to generate proxy classes. (You see an example in my demo solution.)

You see in the graph, that all projects in the outer layers are referencing the core libraries. And not vice versa. I’ve excluded the DependencyResolution project because of the clarity of the graph.

As a reference, I posted here the real “Onion”. ๐Ÿ™‚

Onion Architecture

Onion Architecture

The first version of my demo solution can be downloaded here:

Onion Architecture V 0.1

.

  • Jeff

    What if you were using EF Database First? Where would you put your edmx?

  • DaMi

    The EDMX must be placed outside the core. Otherwise the infrastructure (Entity Framework) gets tightly coupled. I would place it in the Infrastructure. Then you have to map your EF entities to your core domain model.
    Your core defines the repository contracts which are implemented in the infrastructure.
    Here is a statement from Jeffrey Palermos Blog: “Hexagonal architecture and Onion Architecture share the following premise: Externalize infrastructure and write adapter code so that the infrastructure does not become tightly coupled.”

  • Alejandro Segura

    don’t work update with entities relationship one to many, on attach method in datacontext, EF throw exception: An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

  • DaMi

    Hi Alejandro. Can you send me the solution? Or the appropriate .cs files? When does the error occur? (When reading or saving data?)

    You should see my email on disqus (when you log in). Otherwise let me know.

    (In the Repo and DataContext classes are definitely some bugs when trying to update / attach. I didn’t tested the Include etc at all.)

  • Alejandro Segura

    hello dami, send me your email address

  • DaMi

    done. (check your e-mails)

  • roberto diana

    Which version of visual studio I can use the 10 Express?

  • dmicic

    Try express. I never tried before. Should work

  • roberto diana

    I tried but it does not work.
    does not load the solutions …

  • dmicic

    Express 12?

  • roberto diana

    unfortunately for me I have windows xp and it does not work vs2012.

    Which version of vs is created that project? and what libraries are

    Thank you.

  • dmicic

    I used VS.NET 2012. And I think it’s running on .NET 4.5.

  • roberto diana

    I try and tell you how it goes

  • Nice code, thanks!

  • Leandro Andrade

    Sorry if it sounds a stupid question, but why you have an interface for ID? (IdomainIdentifiable)

  • dmicic

    First: I want to force that every “Entity” must have a identification.
    Second: I benefit in the data access layer for example

    public abstract class RepositoryBase : IRepository
    where TEntity : class, IDomainIdentifiable

    By adding the TEntity constraint I can access the ID property of the entity in the generic base class. (For example for comparisons or whatever..)

    Makes that sense? Do you have a better idea? I’m happy to hear! ๐Ÿ™‚

  • Leandro Andrade

    Yeah. That makes a lot of sense. By the way : Great Post! It is being very useful to me.

    I got actually stucked when I was trying to implement a UnitOfWork abstraction in your example.
    I tried to mix your architecture to this repository example :

    https://genericunitofworkandrepositories.codeplex.com/

    which is great apart from one thing I didn’t really like which is couple the Core Domain Model to the Infrastructure DataContext (EF), where every entity implements a class in infrastructure layer that implements ObjectState (which relies on IUnitOfWork if i’m not wrong).So I though that would break straight away the onion concepts.

    Would you have an idea of how to implement this? The benefits I have found on that code is the async transactions as well the ability of bulk transactions).

    Thanks in advance!

  • dmicic

    Nice framework. I never used it before. I usually build a very simple UOW on my own (but without async tx or bulk support). Check my github code: https://github.com/dmicic/Dmicic.Template.ApplicationGeneration

    I configure with DI the UOW as “single” per http context (or WCF request).
    Here:
    https://github.com/dmicic/Dmicic.Template.ApplicationGeneration/blob/master/Dmicic.Template.ApplicationGeneration.Bootstrapper/Boot.cs

    The OnArch.zip code is not a good solution for UOW. I should move the “save” from the RepositoryBase class into a UOW/Context class.

  • Leandro Andrade

    Awsome!
    Thank you!

  • Leandro Andrade

    I am having some issues when opening your solution for the second time on VS 2013. That sounds strange, but that is what it is. When I first open your solution, it goes all good. It asks me to analyse the projects since they are VS2012 if im not wrong, and then if I close and try to open it again, it keeps on loading forever, till I break down the VS Task on Task Manager.

    Well, if I unzip on another folder and open then it opens without problem.

    Have you got any idea of what could that be?

    Thanks in advance!

  • dmicic

    I never open it with VS2013. There is nothing special in the solution.. Strange.. Can’t really help you. sorry ๐Ÿ™‚