Clean Architecture with ASP.NET Core 9

Поделиться
HTML-код
  • Опубликовано: 2 фев 2025

Комментарии • 96

  • @sadukie
    @sadukie 2 месяца назад +20

    Contents:
    01:22 Why Clean Architecture?
    02:56 Layered Architectures
    08:57 Architecture Tests for Enforcement
    09:58 Demo: eShopOnWeb
    16:56 How to Organize Code for Clean Architecture
    21:11 Demo: Ardalis' Clean Architecture Template sample application
    24:20 Demo: Using Ardalis' Clean Architecture Template
    26:25 Learn More - which includes all the links to the repos and sites

    •  Месяц назад

      Thanks!!

  •  2 месяца назад +113

    Does the clean architecture change in every new version of dotnet? 😂

    • @fadouroagoro2639
      @fadouroagoro2639 2 месяца назад +4

      🤣🤣🤣🤣🤣🤣🤣

    • @maacpiash
      @maacpiash 2 месяца назад +14

      Bro asked the real question 😅

    • @ivandrofly
      @ivandrofly 2 месяца назад +1

      ahyahah

    • @ivandrofly
      @ivandrofly 2 месяца назад

      New version of .NET comes with new detergent 🧼🧽 formula 😆

    • @dnzkrblt
      @dnzkrblt 2 месяца назад +1

      Same video have publised a year ago :) ruclips.net/video/yF9SwL0p0Y0/видео.html

  • @Ardalis
    @Ardalis 2 месяца назад +10

    And once again this talk is the most popular (non full day stream) talk in the dotnetconf playlist. Say what you will about Clean Architecture, it remains a very popular if sometimes controversial topic...

  • @sebastiaorelson
    @sebastiaorelson 2 месяца назад +15

    At least once a year I have to watch a video about Clean Archtecture with Jason Taylor and Steve Smith using the current .NET version 😅

    • @Ardalis
      @Ardalis 2 месяца назад +2

      I mean, you don't *have* to... Jason and I just met for the first time last month at Techorama Netherlands. He was doing a talk on CA there (and I was not, I had other talks). It was a great presentation and his template is great, too (though I don't care for its direct dependency on EF).

    • @sebastiaorelson
      @sebastiaorelson 2 месяца назад

      @ is like a classic movie in which you have to revisit every other year, I really like
      Nice to know you have meet Jason can we have a collab?
      Thanks for you amazing work 🙏🏾

  • @tomazkoritnik4072
    @tomazkoritnik4072 2 месяца назад +10

    I would prefer having things in ApplicationCore (and maybe other projects) be organized by functionality. Instead of having folders Entities, Exceptions,Interfaces, Services... I'd rather have one folder for one functionality (vertical-slicing approach). This way one quickly sees which functionalities an application is composed of and it's easier to manage when application grows (otherwise lists just get larger and larger, and no one knows which files belong to which functionality).

    • @Ardalis
      @Ardalis 2 месяца назад

      Agreed 100%. Look for updates to eShopOnWeb along these lines in the future. It has some historical baggage but now that it's maintained by NimblePros I have a freer hand in updating it.

    • @clarkflavor
      @clarkflavor 2 месяца назад +2

      This sounds like a good idea, for sure. Those "service folders" get loaded with tons of files with all sorts of creative naming schemes quite fast..

    • @tomazkoritnik4072
      @tomazkoritnik4072 2 месяца назад

      @@clarkflavor True, it's exactly what layered architecture does and is hated for.

  • @panadolrr
    @panadolrr 2 месяца назад +25

    Every. Single. Year.
    I had some respect for Steve Smith 15 years ago, but after 10 years listening to the same push to "Clean Architecture" it just makes me roll my eyes.

  • @hendrikdevloed
    @hendrikdevloed 2 месяца назад +4

    The templated Core project uses a MediatR dependency and injects a MediatR-specific "IMediator _mediator", wouldn't that count as a forbidden infrastructure reference? I understand the events have to be passed somewhere, but would that require a more general infra-agnostic interface?

    • @Ardalis
      @Ardalis 2 месяца назад +1

      MediatR is just pure C# code, no dependencies on anything out of process. So, it's fine, IMO.

    • @sotsch9280
      @sotsch9280 2 месяца назад

      This is what "Architects" call "We Adopt that to our Architecture" - Sometimes you have to decide for concrete external dependencies, when they serve well, it was a good "adoption" :)

  • @nickdrouin7142
    @nickdrouin7142 9 дней назад

    @Aralis, do you have any resources, links or reading on Clean Architecture in the context of a .NET Maui project. If you know any templates to start from, or repos to emulate, that would be appreciated.

  • @pablo_bf
    @pablo_bf 28 дней назад

    where is the link of the video that explains about "Behaviors"?

  • @SixOThree
    @SixOThree 2 месяца назад +1

    What is the difference between the samples projects and the main projects under root src folder?
    edit: I guess I’ll never find out.

  • @Qrzychu92
    @Qrzychu92 2 месяца назад +1

    I am actually on Team Jimmy Boggard. Just write everything as simple as possible, with code duplication etc, and then refactor away code smells. You will end up writing your own MediatR (so just start with it), and every handler will be in layers - pull data, modify, save (or more those 3). Unit test the modify, integration test the handler - done.
    When you refactor, you will extract shared code into a service - don't start with a service. If you are using EF Core, it already is a repository. If you refactor enough, you will actually get to "DDD but no sweat" - and it's great end goal, not starting point.

    • @Ardalis
      @Ardalis 2 месяца назад +1

      That all works, yes, if you're good at refactoring and know what to refactor *to*. If you don't, having some up front rules or policies to follow can be a big help toward ensuring you don't end up in a hole you can't dig out of. Also, the repository pattern is an abstraction that belongs to your domain model, not a concrete implementation that is part of the framework or some third party. Thus, EF Core isn't "a repository" but is a specific persistence library. There's an important difference.

  • @ChuDevMoHon
    @ChuDevMoHon 2 месяца назад

    I saw your Specification library, it has Specification, So I wondering that TResult is the kind of DTO? but the DTO is staying at UseCase layer if I write a kind of generic specification so I have to define the TResult be some base DTO Class? that make Core layer depends on the layer which DTO stayed. How do you think about that usecase Ardalis?

    • @anhblt
      @anhblt 2 месяца назад

      For additional information, I remembered in previous video, in the slide explain what should be put in Core project, the slide showed "DTO". So DTO can be insided "Core"? Or what usecases that should put it there.
      Also in the template, I think you should prepare for "Grouping", right now our project based on your template and it missing the grouping in Spec so we have to write an "adapter" to adapt the situation.
      Thank you if you have time to read this!

    • @Ardalis
      @Ardalis 2 месяца назад +1

      Specifications support projections, which is what TResult is used for. And yes, that would usually be a DTO. I don't typically like to have DTOs in Core but sometimes it's convenient and pragmatism wins over design purity. More typically I might define projection-based specifications in my UseCases layer, which does define DTOs, and that works as well (although then the specifications aren't all in one place, which is a tradeoff as well).

    • @anhblt
      @anhblt 2 месяца назад

      @@Ardalis Please try to reply my question about grouping above, thank you!

  • @BreakerGandalfStyle
    @BreakerGandalfStyle 2 месяца назад +6

    I think the example project misses somewhat the point of explaining clean architecture, by explaining how to possible do clean architecture in combination with domain driven design.

    • @aguilaaudax1362
      @aguilaaudax1362 2 месяца назад

      actually that is the fucking same shit

  • @4eJIeHTaHo
    @4eJIeHTaHo 2 месяца назад +3

    UseCases Project?

  • @ivanpavlovnorth
    @ivanpavlovnorth 2 месяца назад +9

    All these "Clean Architecture" things look like overengineering for me.
    But overall the idea from ports and adapter architecture of separating business logic from everything and making it the core of the system is very useful.

  • @hyperpaus
    @hyperpaus 2 месяца назад +1

    Specifications are a great idea in theory but nearly impossible to implement with current technology. In your Core project you are not supposed to know anything about persistence. Yet here you are using .Where() and .Include(). This means your persistence layer needs to be able to parse expressions trees for .Where() and .Include() is just a hard dependency on Entity Framework. In conclusion, this implementation requires your core project to have a dependency to EF, and you can only use EF for writing to a database.

  • @hyperpaus
    @hyperpaus 2 месяца назад +1

    Try using this with something else than Entity Framework. Both specification and domain events are hard-wired to EF. This is not good separation at all.

    • @Ardalis
      @Ardalis 2 месяца назад +2

      Both are implementation details. Specifiication has a separate package that provides EF6 or EF Core support. One could add others, or use the library without either ORM if you wanted (though it might be limited to in-memory evaluation at that point so obviously much less useful).
      You can implement domain events wherever and however makes sense for you. Doing it post-persistence is a design choice, and having made that choice, tying it directly to SaveChanges(Async) in the DbContext is simply convenient. But changing that would only require a single change.

    • @hyperpaus
      @hyperpaus 2 месяца назад

      @@Ardalis Thank you for your reply. I agree with the domain events, personally I would just use something like mediator and call it from a service.
      For specifications, it's more difficult. I use clean architecture and I don't use DDD, but I do draw inspiration from it's ideas when making architectural choices. The one DDD concept that has never worked for me is specifications.
      I don't see a way to write a specification that could support the wide range of storage options out there. So you always end up with specifications tied your current choice. In other words your persistence layer leaks into your core layer. Even with the EF implementation as presented in this video, which I used in a project some years ago, I felt very limited. With persistence you need to think about performance, scaling, cost, reliability, ...
      In my personal experience I found that it's impossible to 100% separate persistence from business logic. Either you end up with your persistence layer leaking into your core project, or your business logic leaking into your storage layer. If I have to choose, I prefer the latter. The core is incomplete, but still clean. And you have the full potential of your storage mechanism.

    • @405servererror
      @405servererror 2 месяца назад

      @@Ardalis when you're at the point you have to write a whole new implementation for the specifications, you probably wish you never started with it. You could as well just depend on ef core or hard code them

  • @aspdotnet
    @aspdotnet 2 месяца назад

    I would like to see how to architect a well-structured CRUD. Ultimately, everything ends up with either creating, reading, updating, or deleting.

    • @Ardalis
      @Ardalis 2 месяца назад

      Open Visual Studio with a DbContext and an entity defined. Right click, Add, New Scaffoled Item, CRUD with DbContext. It will do the rest. It's not loosely-coupled code but it's well-structured and will take you < 5 minutes.

  • @BadDogeU
    @BadDogeU 2 месяца назад +1

    Comment section likes writing N-tier solutions where there are 100 "services" with vague logical cohesion... and it shows

  • @StefanValianu
    @StefanValianu 2 месяца назад

    I dont quite understand how moq testing doesn't completely invalidate any concerns about business logic taking a dependency on the data layer. Just write good, mockable interfaces

  • @zikkrype
    @zikkrype 2 месяца назад

    Same year after year. Still something, earlier installing mediatr nuget they used to call the clean architecture

  • @dnzkrblt
    @dnzkrblt 2 месяца назад +2

    It's just the one of the ways of clean architecture. But main idea is same for all of approaches. I think .Net 9 doesn't come any new thing to the clean architecture.

    • @Ardalis
      @Ardalis 2 месяца назад

      Mostly just updates to the packages and the addition of aspire, yes.

  • @alipoustdouzan
    @alipoustdouzan 25 дней назад

    I expected to see at least these four layers:
    Application
    Core or Domain
    Infrastructure
    Presentation
    However, in this solution, I see many projects with weird namespaces and names. In my opinion, this solution is not clean.

  • @TheBendixSA
    @TheBendixSA 2 месяца назад +16

    Dunno man, this seems like the most over-engineered shite I have seen in a long time.... I use .Net so I can ship. Not to sit in architecture meetings for weeks. Hard Pass.

    • @Ardalis
      @Ardalis 2 месяца назад +2

      I mean, just use the template and follow a couple of relatively simple rules and there's no meetings. You're up and running in about 30 seconds. This isn't some complex kubernetes microservices thing. It's just a monolith that's leaning on the compiler to keep dependencies out of the core business logic. It does that well. Beyond that is up to you.

  • @MrAppleruler747
    @MrAppleruler747 2 месяца назад +22

    Bro calls it hexagonal architecture, and only uses 3 sides. My brother in christ, thats a triangle 😅😅

    • @Ardalis
      @Ardalis 2 месяца назад +1

      🤣 *I* didn't invent the name...

  • @clarkflavor
    @clarkflavor 2 месяца назад +2

    What an incredibly sour comment section 😆

  • @stevenstone307
    @stevenstone307 Месяц назад

    After studying and working with Clean Architecture for a while now, I think I'm going to pass on it. I think I'll keep the projects, Application and Infrastructure and all that, I'm just not going to follow the rules so much. I don't want to have to learn how to write my code in a way that fits this architecture. It seems so bloated.

  • @imaginative-monkey
    @imaginative-monkey 2 месяца назад

    I go by 'ardalis' because there are a lot of Steve Smith! 😂 This line should be in a movie! 😎

  • @TTNN0
    @TTNN0 2 месяца назад +11

    If you want to overcomplicate things, just follow this "clean architecture" proposal. This guy talks about domain models but includes foreign keys in them (e.g., OrderId), which reflect database relationships but according to him, shouldn’t be there because "the domain does not depend on infrastructure." 😄 Furthermore, even if you only have one concrete implementation of an interface, you’re still required to create an interface-just for the sake of "high level modules should not depend on the low level ones" and unit testing and mocking. But that’s not true because you can mock concrete classes. :)
    And let’s not even start on the absurdity of DTOs, which, in most cases, look almost identical to the original entity, leading to an unnecessary explosion of DTOs. It’s all just because someone said so, and now it’s become cargo culting.

    • @mateuszkarzek3813
      @mateuszkarzek3813 2 месяца назад

      99% of develepers create interfaces for services, repositories anyway, so... ;)

    • @marcotroster8247
      @marcotroster8247 2 месяца назад +1

      Yeah... backend dev is kinda boring. You can hardly spice it up with some terrible legacy code to make it somewhat interesting 😂😂😂

    • @Ardalis
      @Ardalis 2 месяца назад +1

      You can add id properties to entities and they'll work just fine in a document or NoSql db. No foreign key required. As for the rest, use what adds value and skip the rest. It's a popular architecture, and some of that is because folks find it useful, and some of that is probably cargo cult programming (folks who heard it's cool and use it without really understanding it). You'll have some of that (see: microservices) in our industry. I'm not suggesting this is the only way to build or organize software.

    • @TTNN0
      @TTNN0 2 месяца назад

      >You can add id properties to entities and they'll work just fine in a document or NoSql db. No foreign key required.
      Why would I go with a NoSql database when my needs fit better with a relational database such as Postgresql? I need to have a CustomerId for my Order domain entity, or an OrderId for the Shipment entity as EF will you use these domain models to map everything to the database. Maybe you want to add another layer for EF to work with, but in this case half of the app would be just mapping 😅

    • @Ardalis
      @Ardalis 2 месяца назад

      @@TTNN0 Even if you're using Postgresql, you'll presumably have IDs for related entities somewhere. I think I'm missing your point.

  • @pierre9368
    @pierre9368 2 месяца назад

    "Clean" architecture is not so clean. There is no simple picture that can explain it correctly. Maybe it has a logical flaw? And of course, CQRS and specification allocation have nothing to do with it, they are just smoke and mirrors.

    • @Ardalis
      @Ardalis 2 месяца назад

      The picture is, dependencies flow toward the business logic (core, domain model) and away from UI and Infrastructure. It's a pretty simple circle or stacked boxes picture.
      They (CQRS, specification pattern) are largely unrelated but useful in many scenarios which is why I include/mention them.

  • @runtimmytimer
    @runtimmytimer 2 месяца назад

    If you're following SOLID principles, clean architecture boils down to an exercise of file reorganization and updating of project dependencies. IMHO, all the unnecessarily complicated terminology (aggregate, adapter, etc.) is just that -- unnecessary complication. I think the big take away is "how I can reorganize my source code to minimize dependencies and improve testability."

    • @Ardalis
      @Ardalis 2 месяца назад +1

      Adapter is from Ports and Adapters which is why I mention it. Aggregates are pretty much orthogonal but I think they're helpful and not enough developers know about them so I mention them when I get the chance (which, fair point, maybe overcomplicates the clean architecture discussion).

    • @runtimmytimer
      @runtimmytimer 2 месяца назад +1

      @@Ardalis It's not a knock on you Steve, it's more of a knock on those creating these architecture patterns. My argument is we can do a better job simplifying things. I've been doing this long enough I know complex solutions are very easy to create and simple solutions are very difficult to create -- including patterns. When I first looked at clean architecture my first reaction is this is way too complicated. I eventually realized it's a pattern using Windows Explorer not Visual Studio if already applying SOLID principles. I tell people I like the clean architecture-ish pattern - the version where I've stripped out all the unnecessary complication where I call an interface an interface and an object mapper an object mapper.

  • @Ry4nWTF
    @Ry4nWTF Месяц назад

    yeah don't burn yourself on this with greenfields, start simpler

    • @Ry4nWTF
      @Ry4nWTF Месяц назад

      old heads with experience only with n-tier won't understand

    • @Ry4nWTF
      @Ry4nWTF Месяц назад

      old heads are and graduate will break this, mark my words

  • @marekjakubicki5795
    @marekjakubicki5795 2 месяца назад +7

    Send e-mail on db save changes? So much of single responsibility...

    • @Ardalis
      @Ardalis 2 месяца назад +1

      You understand SRP applies to one class, right? Did you see one class that is responsible for saving changes *and* for sending emails?

    • @marekjakubicki5795
      @marekjakubicki5795 2 месяца назад +1

      @Ardalis You understand that function should do one thing and one thing only? Hiding email sending sooo deep in code, that is already doing another stuff, is bad practice. With another if statement. If I were new team member in this repo, I would neeeever ever have guessed, to search for email sending trigger in db.savechanges.

    • @Ardalis
      @Ardalis 2 месяца назад

      @@marekjakubicki5795 It's true new team members will need to understand events, and the idea that raised events may have handlers in other parts of the system. This is true in any event driven architecture. This is true in UI/front end development where events are commonplace. And it's true here. "What? When I click this button, the code executes something in a whole different file???"

    • @Ardalis
      @Ardalis 2 месяца назад

      @@marekjakubicki5795 This is simply how events work. Whether in UI or in Event Driven Architecture, when you do something and it raises an event, you don't really *know* at that point where the event handler(s), if any, are or what they're going to do. You have to go look. This is no different. There are pros and cons to using events, as with any other architectural or pattern choice.

  • @Raizin-d8p
    @Raizin-d8p 2 месяца назад

    clean architecture 🤮

  • @jordyvu999
    @jordyvu999 2 месяца назад

    Clean Arch is over-architect & not really fit for microservices