0

In Onion framework, outer layer can access all the inner layers. If I go by this, my outer layer (which is UI layer/Controller in MVC) can directly access application/business services and repositories as well. Now, my controller can create a domain model and persist it in datastore by using repository. And thus bypass the validation and other business rules written in business layer. I believe, I am missing something. Please help.

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

from http://jeffreypalermo.com/blog/the-onion-architecture-part-2/

Pragmatic
  • 3,093
  • 4
  • 33
  • 62

1 Answers1

1

I say "no," though Palermo himself has indicated otherwise in twitter conversations. I say that each layer is allowed to talk to the next inner layer and not bypass it. The exception I make to this rule is if the functionality in question is basically just CRUD for reference data. I see no reason to introduce the additional complexity for this kind of data.

Another alternative is to have your repository implementation enforce the validation of business rules. Since the implementation is on the outermost layer of the onion, this should be pretty easy to do.

I have found Alistair Cockburn's Hexagonal Architecture illuminating and simpler that Onion Architecture. Basically there's "inside my application" and "outside my application." Anytime you need to cross that boundary, you need an adapter to protect your application from the implementation details.

Chris McKenzie
  • 3,681
  • 3
  • 27
  • 36
  • If I got you right, you mean to say that there is no need to have wrapper/Pass-through methods in business class for CRUD operation. It is OK to use repository methods in UI. To me, 'Validation of business rules' in repository is not a good idea. This will defeat the purpose of having business layer. – Pragmatic Apr 11 '16 at 04:34
  • There are 2 distinct issues: reference data, and validation. I'll handle them in separate comments. Re: Reference Data Let's say I have a table called StateOrProvince. It may be that I have no business rules for this data other than required fields and uniqueness. These rules can be enforced by the database. There are no operations other than CRUD for this data. Developing a Domain Model for this kind of data might be overkill. I usually just bind my view directly to my ORM in this case. – Chris McKenzie Apr 11 '16 at 14:44
  • Re: Validation You write your validation logic in your domain layer. You should have abstractions that represent your persistence layer defined in your domain layer that your domain objects can use. There is no reason you cannot `invoke` your domain object's validation logic in the implementation of your persistence layer. In fact, if you look carefully at the OA diagram, the implementation of persistence is on one of the outermost rungs of the diagram. This means that you get the full context of the Domain in your persistence layer. You might as well use it. – Chris McKenzie Apr 11 '16 at 14:47
  • One last thing - I found the Pluralsight video on Domain Driven Design Fundamentals to be super helpful around these kinds of questions. https://app.pluralsight.com/library/courses/domain-driven-design-fundamentals/table-of-contents – Chris McKenzie Apr 11 '16 at 14:49