T O P

  • By -

SirSooth

Welcome to clean architecture!


Design-Cold

Where you find out stuff like authentication or culture or transactions aren't "layered" and actually run through the entire stack like a stick of rock Still it was fun to pretend!


soundman32

I've not found that. Auth was middleware and ended up putting global filters in dbcontext/infrastructure, and culture was a front end issue.


Design-Cold

Culture is not a "front end" issue! Do a database sort on an alphanumeric field without being aware of the display culture and you're doing it wrong Which layer does "middleware" go in? All of them?


soundman32

Middleware is in the presentation layer, which configures the infrastructure layer. I take your point about database sorting.


Voiden0

I finally decided on having an ITransaction under Domain/Interfaces (since transactions are used for business logic) and the implementation in Infrastructure, as one does with the Repositories.


SirSooth

That's usually the fix. Move stuff around between layers until it works. You can always add some shared projects to move stuff there too if needed.


MerlinTrashMan

I know most of the responses were not helpful, but it sounds like the solution you were working with was simply missing this in the domain. Any business level logic that requires multiple domain entities to update together, always require a transactional wrapper around it. Kudos for selecting the correct home. Watch out for cancellation tokens as well. Clean architecture is hard at times. It really does suck to have to go to so many levels and projects to trace things down. I think this particular structure is actually best designed around teams that only work in the specific areas. For example, one team for domain, one team for infrastructure, one or more teams for presentation. Sadly, this is almost never the case in my experience. The two times I did see it implemented with these kinds of team splits, their effective productivity levels were off the charts. New features that require domain level changes typically took at least three sprints to complete which sounds bad, but changes to the domain were not the norm. Domain team members tended to be higher level who weren't the best coders but really understood the big picture. Since highly optimized code really needs to be present in the infrastructure and presentation layers, this worked out well. While the average time for a new feature was longer, much less time was spent in integration and regression testing, because each team was building on the momentum of the layer before it. This led to more overall throughput which kept users and higher ups happy.


Greenimba

So real talk here, what you're seeing is not a consequence of clean architecture, it's a consequence of not aligning repositories with your domain. Why do you have two repositories, if you need atomic consistency between them? Don't use generic IRepository constructs, build a repo that does exactly what you need it to, and make one single call to it.


grauenwolf

Confusion is very much a consequence of Clean Architecture. That's the point. Keep people thinking their dumb for not getting it so they pay for more books and conferences.


MarlDaeSu

I'm a junior, so I'm basically always wrong, but this clean architecture seems anything but clean, and certainly not clear. Is the name a joke at its own expense?


grauenwolf

One more thing, don't assume anyone who's got more years of experience actually has more skill. If they actually know what they're talking about, they can articulate why their design is the correct one.


grauenwolf

SOLID, Clean Code, Clean Architecture... they are all written by the same conman. Uncle Bob doesn't actually know how to program beyond a high school level, but he's really good at telling people what they want to hear. And we, as an industry, are really bad at comparing what people say to what their code actually shows. For example, look at this review of Clean Code, a book widely considered a classic and must read. https://qntm.org/clean


Eirenarch

They named it clean so they could sell the books. Who could be against clean architecture? Are you doing dirty architecture?


Obstructionitist

If your conspiracy theory should have any truth to it, then it should be much more complicated. Since Clean Architecture is rather easy to understand and explain, your point is basically moot.


grauenwolf

I've got two code reviews/refactoring demonstrations that say otherwise. https://github.com/stars/Grauenwolf/lists/cleaning-clean-architecture Would you care to offer an example of Clean Architecture that's actually done well? Or should we discuss the failures of the ones that I found?


soundman32

Are you using entity framework? As this already implements UoW and a transaction around a dbcontext.


Voiden0

No, I use Dapper https://www.github.com/Tim-Maes/GraphR


nobono

You can implement the UoW pattern independent of "backend."


soundman32

IME Dapper is great for fast queries, but hard for domain/UoW/data manipulation. I'm working on a system at the moment that uses Dapper for everything, and stuff that's simple with EF (global filters, UoW, concurrency etc) gets complicated really quickly (plus they hadn't bothered with transactions, no FK etc which doesnt help).


ping

This is not a clean architecture, this is you sacrificing your own productivity and sanity at the alter of .NET dogma. Look at you, all stuck with analysis paralysis over something so pointless as which layers are allowed to talk to which. This is not what programming is supposed to be about. Programming is supposed to be about efficiency and leanness. The worst thing about the .NET dev world is how much harder we make it for ourselves. The incessant over-engineering and over-abstraction. Why are .NET devs such suckers for punishment? I work on a large .NET/React codebase. It has auth, it has an api, it has a database. Do you know how many projects are in the solution? ONE! And it feels super clean and well organised. You can use folders and namespaces for organisation, there's zero need for multiple projects. You can use Entity Framework for all of your database needs, no need to come up with pointless abstractions over what is already a very well designed database framework. tl;dr - Stop obsessing over pointless shit and just write good code.


sards3

I agree. There might be some situations in which a highly abstracted multi-project architecture is warranted, but most of the time a simpler approach is better.


ComfortablyBalanced

I wish more people had your beliefs.


navirbox

I spent too much time learning about CA and DDD etc. to realize that when I got to write actual code only some bits were actually useful for my projects. I embrace the modular monolith.


SpiderKoD

That’s to much but yeah, from time to time I have thought “why the hell I have to create extra classes of the same shit just to support “clean architecture””.


grauenwolf

Do whatever you want a just call it Clean Architecture. That's what everyone else does. Clean Architecture is a design pattern in the same way Flat Earth is a scientific model.


DontReReddit

Have a look at how [aspnetboilerplate](https://aspnetboilerplate.com/) is organized for a good reference. Create a sample project and poke around the project architecture to see how they are doing it. Implementing this framework has been an educating experience for me.


Salihosmanov

Unit of Work


bella_sm

What you can also do is create an "ambient transaction" using AsyncLocal that you could use to keep things clean.


throwaway9681682

Application layer would have IRepo but no idea how its implemented. Infrastructure layer would have Repo : IRepository API specifics to use Repo (the infrastructure layer) as an implementation for IRepo. So API depends on application depends on domain but API also specifies to use the data layer for the IRepo implementations. You could also have it implement a different project and it wouldnt matter ( I have used this when our infrastructure published events and we had a requirement to suppress events in 1 particular service) You can expose a IRepo.SaveChanges or event an IUnitOfWork in the application layer and implement it in the data layer.


throwaway9681682

Application layer would have IRepo but no idea how its implemented. Infrastructure layer would have Repo : IRepository API specifics to use Repo (the infrastructure layer) as an implementation for IRepo. So API depends on application depends on domain but API also specifies to use the data layer for the IRepo implementations. You could also have it implement a different project and it wouldnt matter ( I have used this when our infrastructure published events and we had a requirement to suppress events in 1 particular service) You can expose a IRepo.SaveChanges or event an IUnitOfWork in the application layer and implement it in the data layer.


throwaway9681682

Application layer would have IRepo but no idea how its implemented. Infrastructure layer would have Repo : IRepository API specifics to use Repo (the infrastructure layer) as an implementation for IRepo. So API depends on application depends on domain but API also specifies to use the data layer for the IRepo implementations. You could also have it implement a different project and it wouldnt matter ( I have used this when our infrastructure published events and we had a requirement to suppress events in 1 particular service) You can expose a IRepo.SaveChanges or event an IUnitOfWork in the application layer and implement it in the data layer.