5

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 "clean architecture"

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?

9
  • 1
    1. No. In this particular variant of the design, the Interactor pushes the OutputData to a (likely void returning) method on the boundary interface; the presenter basically acts as a handler for that push, and it reacts by updating the ViewModel. 2. The classes in an outermost layer usually have to depend on types frameworks/drivers in order to adapt them (the dependency on lower level policies is encapsulated within them, but the overall component follows the dependency rule); usually, the framework will let you derive from a controller; design it so that the framework is isolated there.CommentedMar 26, 2020 at 12:26
  • 1
    5. Yeah, treat these essentially as two separate applications for the purposes of internal organization; "the web is a detail" just means to put web-related details in each application behind an adapter. "The web" is not Angular, the backend doesn't know about Angular. For the backend "the web" is API entry points, controllers, routing, the web framework. For the frontend, "the web" are the API calls. (Skipped over 3. & 4.)CommentedMar 26, 2020 at 12:27
  • 1
    About 5: Yeah! It's all the same thing - it's the stuff on the periphery! When you are making API calls to the backend, you are sending web requests; when the backend is making database calls, it is doing so over the database API (people are often confused about this - forgive me if that's not the case with you - but the term API is not particularly related to REST/web; an API is the interface to some system (public methods, data structures, classes, formats, protocols, etc.) that you use when you program. 1/4CommentedMar 26, 2020 at 20:49
  • 1
    Angular is not exactly "web" in this sense, it's a frontend platform; an angular app is just a JavaScript application (it's basically a desktop app that happens to run on the browser; it's all executed client side). The core of the application can be made web-agnostic; at the periphery, you make web calls to various services, on one end, and make updates to those templated views on the other, which the framework ultimately renders to HTML. 2/4CommentedMar 26, 2020 at 20:49
  • 1
    About 1: The push can just be a method call on the interface. The dependencies depicted are static dependencies; at runtime, the interactor has a reference to the presenter, but the type of the variable is the OutputBoundary interface (dependency inversion); the interactor can simply call a method and pass on some parameters (OutputData). The presenter maintains a view model reference, and can then update it in that method's body as appropriate. This can be done with actual evens as well, but that's not required. 3/4CommentedMar 26, 2020 at 20:49

1 Answer 1

17

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) intoa "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.

1
  • 1
    Thanks for this detailed answer. I am really happy to get some better understanding now! Wow.CommentedMar 26, 2020 at 21:56

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.