Onion Architecture should we inject domain models into the presentation layer?

1.3k Views Asked by At

I am trying to implement an Onion architecture for a ASP.Net MVC 5 project. I have seen opinions that services should be injected rather than instantiated even though, correct me if I am wrong, the idea expressed by Jeffery Palermo (http://jeffreypalermo.com/blog/the-onion-architecture-part-3/) was that any outer layer should be able to directly call any inner layer. So my question is

  1. Can the onion architecture work without IOC, and if yes, is it ideal?
  2. Let's say we go with IOC, if the UI should not know about the actual implementation of domain services, should we apply the same principle to the domain models themselves e.g. injecting models into the UI instead of referencing them directly?

I am understand why some solutions apply IOC on domain services but are accessing the domain models directly in the controllers.

2

There are 2 best solutions below

6
On

OA can be thought of as n-tier architecture + Dependency Injection--so you would be hard-pressed to implement OA without IOC.

Regarding outer layers using any inner layer, I personally disagree with Palermo on this point. I think that outer layers should be constrained to working with the next layer in (to restate: outer layers should not be allowed to bypass a layer). I asked him about this on twitter once and he said that it's probably not a good idea for the data access implementation code to work with the presentation layer (remembering that the implementation code is on the outer rim of his architecture).

I think Palermo makes room for bypassing a layer precisely because he wants to be able to manipulate a Domain Models and Domain Services in the Controller. As far as I understand Domain Driven Design, Domain Services are only created when logic does not neatly fit into a Domain Model. If that is the case, then Domain Services and Domain Models are not really 2 separate layers. Rather, it's better to think of them as a single Business Layer. If they are both the same layer, then the question of whether you can use both in a Controller resolves itself. Then you can say without contradiction that outer layers should be constrained to talking to the next layer in the onion.

0
On

First, remember that the Onion Architecture (OA) is agnostic to application design styles, so there is nothing stopping you from injecting your domain into the UI. Second, the linked article points out that IoC is core, so you won't want to try to go without it. I'm also surmising you're talking about your domain entities - those things with data/state in your domain.

OA is about shielding your domain (business rules, entities, etc) from the vagaries of infrastructure changes, not the other way around. All you're buying yourself by using interfaces to get to your domain is extra code and indirection. Ask yourself this - If my domain changes (the core of your business), is it realistic to expect my user interface won't? Put another way, if your business rules change, the users are probably going to want to see that reflected in the UI if it involves adding or removing fields or whole lines of business.

Now ask the inverse of that question - If I change from Oracle to NoSQL, will my Domain code change? Injection of your infrastructure laden services is meant to give you the answer "No". This presumably means easier to maintain and more stable code.

So, in conclusion, unless you need to hide logic on your domain entities, or there is a compelling architectural reason against it (e.g., you're flinging these out of your server to a remote client or you want to add UI-specific attributes to your properties to affect validation or label display), you should go ahead and reference your concrete domain entities directly in your "application/UI" layer.