Welcome to the 75th edition of The Catch Block!

In this edition: how should controllers interact with repositories or services? A musing on architecture in modern apps.

Plus: a bunch of .NET and VS news; the 2021 edition of the OWASP Top Ten; changing your blog to dark mode automatically; technical debt as stocks; and the surprisingly interesting history of time zones.

Controllers, Repositories, Services

Steve "Ardalis" Smith does it again with an article about whether controllers should reference low-level repositories, or mid-level services:

Should Controllers Reference Repositories or Services
A common question students ask when learning about Clean Architecture, SOLID, and/or DDD is whether controllers (or razor pages or API endpoints) should work with repositories directly, or if they should only communicate with services. As with many questions in software, the answer is, “it depends”,…

A common problem in software architecture is "how much is too much", and the answer is always "it depends". Steve's article points out a few cases in which "endpoint" classes, including controllers, should reference the lowest-level repository classes, or use an intermediate class such as an application service.

The point his architecture is trying to make is to separate the business logic from both the controllers and the repositories. One way, he suggests, is to put that logic in the domain model itself. In this way, the business logic is separate from both endpoints and repositories but is still directly related to the domain.

As it always is, the problem arises when we need more complex logic. For logic that is more complex than a single domain object, where should it exist? Here, Steve suggests that it might be reasonable to create an application service, which processes data from the repositories and gives the processed result to the endpoints or controllers. I wrote about a similar architecture (which I named the Repository-Service Pattern) a while back:

The Repository-Service Pattern with DI and ASP.NET Core
Let’s build a complex but useful architecture called the Repository-Service pattern to clearly enforce separation of concerns.

The key to all of this, Steve notes, is this: keep your architecture consistent in terms of the abstraction layers it implements. If you need only controllers and repositories (if, say, you're really only doing CRUD operations), then stick to that. Don't add unnecessary complexity, and don't make things too simple.

And, really, isn't that what we developers should be trying to do anyway?

This article is for paying subscribers only

Sign up now and upgrade your account to read the article and get access to the full library of articles for paying subscribers only.

Sign up now Already have an account? Sign in