Clean Architecture with ASP.NET Core 9

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

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

  • @sadukie
    @sadukie Месяц назад +15

    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

    •  11 дней назад

      Thanks!!

  •  Месяц назад +102

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

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

      🤣🤣🤣🤣🤣🤣🤣

    • @maacpiash
      @maacpiash Месяц назад +12

      Bro asked the real question 😅

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

      ahyahah

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

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

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

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

  • @Ardalis
    @Ardalis 20 дней назад +7

    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...

  • @panadolrr
    @panadolrr Месяц назад +24

    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 Месяц назад +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 Месяц назад +1

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

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

      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" :)

  • @sebastiaorelson
    @sebastiaorelson Месяц назад +13

    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

      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 Месяц назад

      @ 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 Месяц назад +8

    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 Месяц назад

      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

      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 Месяц назад

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

  • @SixOThree
    @SixOThree Месяц назад +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.

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

    UseCases Project?

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

    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 Месяц назад

      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 Месяц назад

      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 Месяц назад

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

  • @BreakerGandalfStyle
    @BreakerGandalfStyle Месяц назад +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.

  • @ivanpavlovnorth
    @ivanpavlovnorth Месяц назад +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.

  • @Qrzychu92
    @Qrzychu92 28 дней назад +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 20 дней назад +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.

  • @hyperpaus
    @hyperpaus Месяц назад +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

      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 Месяц назад

      @@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 28 дней назад

      @@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 20 дней назад

    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 20 дней назад

      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.

  • @imaginative-monkey
    @imaginative-monkey 19 дней назад

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

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

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

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

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

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

    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

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

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

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

    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.

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

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

  • @dnzkrblt
    @dnzkrblt Месяц назад +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 Месяц назад

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

  • @TheBendixSA
    @TheBendixSA Месяц назад +14

    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 Месяц назад

      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.

  • @clarkflavor
    @clarkflavor Месяц назад +1

    What an incredibly sour comment section 😆

  • @TTNN0
    @TTNN0 Месяц назад +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 Месяц назад

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

    • @marcotroster8247
      @marcotroster8247 Месяц назад +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 Месяц назад +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 Месяц назад

      >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 Месяц назад

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

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

    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 Месяц назад

      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 Месяц назад +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.

  • @pierre9368
    @pierre9368 23 дня назад

    "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 20 дней назад

      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.

  • @Ry4nWTF
    @Ry4nWTF 18 дней назад

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

    • @Ry4nWTF
      @Ry4nWTF 18 дней назад

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

    • @Ry4nWTF
      @Ry4nWTF 18 дней назад

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

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

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

    • @Ardalis
      @Ardalis Месяц назад +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 Месяц назад +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 Месяц назад

      @@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 Месяц назад

      @@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 28 дней назад

    clean architecture 🤮

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

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