Question

I just read the book 'clean architecture' by Uncle Bob and really like the approach. But the big disappointment came when I tried to implement it in C#. I really hope you can help me with some questions.

enter image description here

What I tried was to implement the following component diagram:

sample from the book

A = Enterprise Business Rules

B = Application Business Rules

C = Interface Adapters

D = Frameworks & Drivers

But some things seem strange to me:

  1. A presenter converts the "OutputData" (with for example date objects) in "ViewModel" (that has only strings and flags). So the interface "Output Boundary" could have a function "present" with a parameter of type "OutputData" and return a value with type "ViewModel". But Output data is not allowed to have a code reference to "ViewModel", so how should this work?

  2. The outer most layer is the only layer where "Frameworks" are allowed. But in frameworks the "controllers" are usually build into the framework. So do I have to build a wrapper? So I would put controllers of the framework in the outermost layer and my own "architecture controllers" to the adapter layer? Seems like over engineering to me.

If I look at concrete implementations on the web, this does not really answer my questions.

For example this guy created a project with three components:

Web.Api - Maps to the layers that hold the Web, UI and Presenter concerns. In the context of our API, this means it accepts input in the form of http requests over the network (e.g., GET/POST/etc.) and returns its output as content formatted as JSON/HTML/XML, etc. The Presenters contain .NET framework-specific references and types, so they also live here as per The Dependency Rule we don't want to pass any of them inward.

Web.Api.Core - Maps to the layers that hold the Use Case and Entity concerns and is also where our External Interfaces get defined. These innermost layers contain our domain objects and business rules. The code in this layer is mostly pure C# - no network connections, databases, etc. allowed. Interfaces represent those dependencies, and their implementations get injected into our use cases as we'll see shortly.

Web.Api.Infrastructure - Maps to the layers that hold the Database and Gateway concerns. In here, we define data entities, database access (typically in the shape of repositories), integrations with other network services, caches, etc. This project/layer contains the physical implementation of the interfaces defined in our domain layer.

  1. He is not the only one out there having a layer called "infrastructure". But I did not find this layer in the book. Where does it come from? Sometimes people use it for database access, sometimes for services. Where does the term "infrastructure" come from?

  2. He puts "Web, UI and Presenter concerns" in the Web-Layer. So he mixes layers.

  3. On web applications - like an SPA with Angular that accesses an API in the background, I think that my web application should have its own "clean architecture" like described here. My .NET core application on the server also has its own "clean architecture". This makes sense to me. But uncle bob states that "the web is a detail", so this looks like he would treat Angular only as a "detail" and the UI. But probably he did not think of SPAs while he wrote the book... SPAs can have a part of the business rules. So how do you deal with that?

Was it helpful?

Solution

I just read the book 'clean architecture' by Uncle Bob and really like the approach. But the big disappointment came when I tried to implement it in C#. I really hope you can help me with some questions.

You don't implement Clean Architecture. You follow it, as you implement something else.

Even if all you're doing is creating a reference implementation remember, Clean Architecture is not the goal. It's only a means to get there. It's certainly not the only one.

  1. A presenter converts the "OutputData" (with for example date objects) in "ViewModel" (that has only strings and flags). So the interface "Output Boundary" could have a function "present" with a parameter of type "OutputData" and return a value with type "ViewModel". But Output data is not allowed to have a code reference to "ViewModel", so how should this work?

No, a presenter converts an "OutputData" (with for example date objects) into a "ViewModel".

Pay attention to the little <DS> in the corners of some of these not exactly UML boxes. DS stands for Data Structure. You're not going to find any external references in the Data Structures. All arrows point to the Data Structures. None point out from them. They don't know about anything but themselves.

So the interface "Output Boundary" could have a function "present" with a parameter of type "OutputData"

Yes.

and return a value with type "ViewModel".

No. You can't return ViewModel to the Use Case Interactor (the only thing that could have called "present") because the Use Case Interactor doesn't know what a ViewModel is.

What could happen is the Use Case Interactor could build an OutputData and then pass a reference to it through the Output Boundry to the Presentor which would use it to construct / update a ViewModel.

It's helpful to remember that the <> stuff (<I>&<DS>) can't call anything.

I've talked about this before and created this animated gif to show the flow of control:

enter image description here

  1. The outermost layer is the only layer where "Frameworks" are allowed. But in frameworks the "controllers" are usually build into the framework. So do I have to build a wrapper? So I would put controllers of the framework in the outermost layer and my own "architecture controllers" to the adapter layer? Seems like over engineering to me.

Give a perfectly sensibly engineered automobile to a 5 year old who wanted a tricycle and you could argue that it's over engineered. Clean Architecture is not one size fits all. It gives you flexibility and power at the cost of extra effort. It's up to you to decide when you really need that.

In this particular case it would give you the flexibility that comes from expressing only your real needs that the framework fulfills thus making life easier for those who come later to replace the framework or repair it when it experiences a breaking change. If you don't care about any of that now nothing can make this worthwhile. Just call it "technical debt" and move on.

  1. He is not the only one out there having a layer called "infrastructure". But I did not find this layer in the book. Where does it come from? Sometimes people use it for database access, sometimes for services. Where does the term "infrastructure" come from?

It comes from this:

enter image description here

Look in the outermost lower right hand sector.

You've likely confused Clean Architecture with Onion Architecture. Same idea, different vocabulary (created to drive you to different blogs and books).

Getting them confused is an understandable mistake. Both of these are rehashes of Alistair Cockburn's idea of Hexagonal Architecture (that he's also called Ports and Adapters).

Collectively I call them The Buzzword Architectures because the main difference between them is the vocabulary that decides who gets your time and money when you learn about them.

One thing that unifies them is that they all let you create an architecture free of cycles that still manages to effectively communicate. This helps ensure a code change hits a firewall soon rather than spreading through the code base breaking component after component.

  1. He puts "Web, UI and Presenter concerns" in the Web-Layer. So he mixes layers.

Nobody's perfect.

  1. On web applications - like an SPA with Angular that accesses an API in the background, I think that my web application should have its own "clean architecture" like described here. My .NET core application on the server also has its own "clean architecture". This makes sense to me. But uncle bob states that "the web is a detail", so this looks like he would treat Angular only as a "detail" and the UI. But probably he did not think of SPAs while he wrote the book... SPAs can have a part of the business rules. So how do you deal with that?

How much of your application really needs to know that the web exists? The central theme of all these architectures is isolating knowledge. You're tempted to spread the idea of the web around until all you're working on is a web app. Sure, it's quick and easy now. Be sure it's something you're willing to live with. Because once you do this, taking it back isn't easy.

Licensed under: CC-BY-SA with attribution
scroll top