How to structure a .NET Solution (project separation & architecture)

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

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

  • @nickchapsas
    @nickchapsas  3 года назад +97

    Hey everybody I just wanted to make something clear in case it wasn't clear enough in the video. I also don't agree with the use of Entity Framework for the project. The video focuses on the projects, layers and concept more than it focuses on the actual tech used. You can remove EF, MediatR and any other piece of tech but as long as you keep the idea behind it as it is, the concept still stands.

    • @LonliLokli
      @LonliLokli 3 года назад

      Idea is almost great :) Do you have github link with this sample to fork and modify smth?

    • @nickchapsas
      @nickchapsas  3 года назад +4

      @@LonliLokli The link to the project can be found in the description

    • @shreyasjejurkar1233
      @shreyasjejurkar1233 3 года назад +12

      Abstracting EF core is quite hard task! Jason has added EF dependency in Application layer, because 80% time it will be the default choice for .NET projects!

    • @LonliLokli
      @LonliLokli 3 года назад

      @@shreyasjejurkar1233 abstraction is required only for input and output types ie domain objects.

    • @akires47
      @akires47 3 года назад +13

      I'm using Jason solution for every project i have and using in production too, but i added on this architecture the repository pattern too, so i only have a dependency of EF on the infra layer, and all my applications just inject the repository interfaces, so if i wanna change from PostgreSQL to CosmosDB just change the way of recover of the data on the repositories, this use case just happens to me 1 week ago, and in 1 day i changed everything without refactoring anything on logic/app layer.

  • @Chiramisudo
    @Chiramisudo 3 года назад +65

    Now THIS is a rare find. Almost nobody talks about how to structure your projects, but it is actually quite important, especially for new team members trying to familiarize themselves with an unfamiliar codebase. Excellent structure and lesson! Cheers!

  • @shayvt
    @shayvt 3 года назад +116

    Can you please make a video on Unit Tests and Integration Tests architecture, best practices, etc.?

  • @thefarhadfarhadi
    @thefarhadfarhadi Год назад +1

    You learn much more when you read a good book later. I saw this video previously maybe one year ago, now I've watched it again and god I see things differently now.
    Thank Nick for your great contents.

    • @keipala
      @keipala 9 месяцев назад

      What was the book?

    • @stefano_schmidt
      @stefano_schmidt 9 месяцев назад

      ​@@keipalamaybe the Clean Architecture (Robert C. Martin) itself

  • @Eugene.g
    @Eugene.g 3 года назад +3

    Jason Taylor's repo is exactly what I'm using as a reference for the last 8 months. My app's codebase has grown a lot since the beggining of development and I can say everything is still really great 👍

    • @nickchapsas
      @nickchapsas  3 года назад +1

      Nice! Out of curiosity are you using the same MediatR CQRS approach or are you coding "Service" classes that take care of the different operations?

    • @Eugene.g
      @Eugene.g 3 года назад

      @@nickchapsas I use CQRS with Mediatr. Sometimes I put things into services if I need to reuse some logic between handlers. CQRS feels great for me, much better than the service hell I got in Angular. I even dream of implementing separate read model in those places which are most request intensive some day and adding some Event Sourcing where it's applicable

    • @oldwhitowl
      @oldwhitowl 3 года назад +1

      @@Eugene.g Hi Eugene, i'm pretty new to Clean Architecture and DDD and I'm not a massive EF fan. I'd like to use CQRS and wondered if you could guide me as to how you have implemented within this solution architecture? I'm probably going to using dapper/sql server. I'm unsure what the ApplicationDbContext would be replaced with? Would this be a class which references dapper and exposes a simple Query/Command generic interface? Or do you have a specific class per query/command? The application layer currently has a folder/class per query/command using Mediatr, if i removed Mediatr i would reference these classes (DI) via the API/Client layer controllers? Saying that Mediatr looks quite cool and never used it so probably a good opportunity to learn. Any guidance would be really appreciated. Thanks

    • @Eugene.g
      @Eugene.g 3 года назад +1

      ​@@oldwhitowl Hi Lee. You can replace DbContext with any Repository implementation. You can just put your repo in the Infrastructure layer and inject it into a Command/Query. It can be a generic repo, or a separate repo class for a particular model
      DbContext is an implementation of the Unit of Work pattern and DbSet implements Repository. You can make changes in different DbSets and then fire SaveChangesAsync() on DbContext, and it will save all tracked changes to DB. UoW is convenient if you use rich Domain Model. Jason Taylor's template is using Anemic Domain Model which is controversial. Some say it's fine, some say it is an anti-pattern. BTW you can use EF in Commands and Dapper in Queries
      CQRS is a simple concept. You just need Command/Query class which is a simple DTO and a Handler class which is just holding operations with that DTO as input parameters. You can implement it yourself and use your handlers from controllers. MediatR is good if you need to wrap your Commands/Queries with behavior like logging and benchmarking, but it's not necessary
      Glad if it helps you

    • @oldwhitowl
      @oldwhitowl 3 года назад

      @@Eugene.g Many thanks Eugene. I think i will try the EF and dapper route. I have used CQRS before and have always had a class per thing (query/command), GetCustomer/UpdateCustomer etc but didn't know whether to go down the repo route of say Customers and group everything. I think I have read too many articles on the subject as my head is spinning as each author has a different opinion on how things work and where things should be located.
      I have seen solutions with use cases in the domain layer which I thought should go in the application layer, this tends to be when the author defines the domain layer as application specific rather than enterprise specific.
      Regarding Rich Domain Models, would these sit in the domain layer and contain some logic? This is something Nick in this video was against, logic in the domain layer. To confirm also, the model methods would only affect the model internal data and it would be the application layer to use that model to update a DB via the infrastructure layer and dapper/EF?
      Thanks again!

  • @Imafriggingoddess
    @Imafriggingoddess 3 года назад +7

    Awesome video! I've been working as a professional dev for 1.5 years but I've felt I've been lacking in architecture for a while now. These videos really help.

  • @rogeriobarretto
    @rogeriobarretto 3 года назад +36

    Hi Nick, can you post or share a full implemented example of how you use the Application + Contracts + Client + SDK + WebUI in a API Solution scenario ?
    Very good content, congratz!

  • @darylolson5089
    @darylolson5089 3 года назад +2

    I use the project structure and dependencies as outlined in this video with one difference. I add a project "DependencyInjection" which references: Application, Domain and Infrastructure. Then WebApp only needs to reference Application and DependencyInjection.
    To ensure that the dependency references are maintained going forward, I write Fitness Function tests that check that the dependencies between the projects are not violated. It is extremely easy to inadvertently break these dependency rules.

  • @malikehsan147
    @malikehsan147 3 года назад +4

    A ton of thanx for explaining why Infrastructure is referenced in the Presentation. I just wondered seeing Infrastructure referenced in the Presentation after creating the solution. But Jason said in the video that Infrastructure and Presentation should not depend on each other. Thanx again for the clarification.

    • @samwdp
      @samwdp 3 года назад +1

      He explains why the Presentation layer references the Infrastructure layer at 9:11. The reason why is for Dependency Injection ONLY. The only reference you will find to the Infrastructure layer in the Presentation layer is in Startup.cs when all the services are being added to the DI container. Hope this helps

    • @torrvic1156
      @torrvic1156 10 месяцев назад

      @@samwdpthe other way is to create s CompositionRoot as a separate project and allow only it to include dependency injection but honestly I don’t think that it’s worth it.

  • @megaman2016
    @megaman2016 2 года назад +10

    In your example, the application layer will change if you changed databases because the return type DbSet is entity Framework specific

    • @henry-js
      @henry-js 2 года назад +1

      You can use different databases with Entity Framework

    • @denipop83
      @denipop83 Год назад

      @@henry-js what about redis? mongo? elastic? no, you can't. so in this example, it's not a pure clean architecture, there is leaky abstraction

    • @funarfiif982
      @funarfiif982 Год назад

      @@denipop83 If you move from relational to non-relational, your change is not just the data persistence abstraction, it's probably across ALL layers.

  • @umut9780
    @umut9780 3 года назад

    I don't think people realise how valuable and important these kind of guides are, and it's unfortunate how they do not go to enough detail on this exact topic the way you do. As a dev you learn to code first, how things work, you chuck your code everywhere all willy-nilly to just make it WORK. But it gets to a point where once you get that experience, learning how to do things the right way is very important too. Thanks for sharing content like this!
    Also this is one approach, a very good one at that. There are also other approaches which are very good too because they share similar principles.

    • @Blaisem
      @Blaisem 2 года назад

      I am new. Why is it important to separate dependencies? What are the risks if your code isn't organized in a manner similar to this video's suggestions?

  • @ryanjohnson4845
    @ryanjohnson4845 3 года назад

    This is great. I have a similar setup for what I work on. The key difference is I manage a suite of apps that share domain models, repository access, logging etc. So I have those common things in a separate solution. Those projects are now NuGet packages hosted on GPR. So practically 0 code duplication for these common things and a simple way to deploy changes.
    For dev, I have a post build script that copies the .dll files to the appropriate folder in the nuget cache, so I can test integration immediately.

    • @nickchapsas
      @nickchapsas  3 года назад +1

      Yeap I have answered this in a few comments as well. Since a lot of that is enterprise wide, especially the domain layer, it can easily be packaged and shared across multiple projects

  • @karimpeymani6569
    @karimpeymani6569 Год назад +1

    Thanks Nick, This is very clear of explanation for architecture.

  • @gabriel.andreato
    @gabriel.andreato 3 месяца назад

    Amazing, I never had seen anyone showing in code this level of examples, thankse

  • @buildingphase9712
    @buildingphase9712 2 года назад +5

    In the future with that implementation, you can not move from entity framework because the repository interface contract expects DbSets types. Thus you are tightly coupled to EF there unless modified.

    • @d03090
      @d03090 2 года назад +1

      This is exactly what I am thinking and I can't get my head around it. In the old days EntityFramework (EF) was something that was living in the DataLayer if you wanted to use it. The BusinessLogic/Application used an interface to say "hey, please update this ToDoItem" and didn't care on how an implementation of this interface would save it. It could have been a SQL DB, DynamoDB or an CSV file. With this new structure it is like "hey, please update this ToDoItem, but you must use EF for it!". Now you would have to write some custom EF provider to satisfy the interface requirements. And if you don't want to use EF the whole application fells apart, because all these Commands and Queries are dependent on DbSet and you have to rewrite every command and query. Am I missing something?
      How do you deal with this @dzimbadzemabwe zw? And what are your thoughts about this, @Nick Chapsas?

    • @buildingphase9712
      @buildingphase9712 2 года назад +1

      @@d03090 100%, l always define a repository interface that has no framework dependency at the application level, just a pure C# contract is always my aim for most cases, i.e "expect a list of ToDoItems". Then the infrastructure can implement this however way l want for as long as l implement the contract. Its rare cases l corner myself with interface implementations that box me to a framework, in this case EF, what happens if we want to use Dapper, we are now going to be changing our code in many places, this breaks SOLID and extensibility in my opinion, in the end it all comes down to use case, if you want the software to last 20 years it is very important to think about these things.

    • @d03090
      @d03090 2 года назад +1

      @@buildingphase9712 Thank you for you explanation. Yes, this makes a lot more sense to me.

    • @williambaker3961
      @williambaker3961 2 года назад

      I think this template/architecture is based on YAGNI (You aren't gonna need it). How often have you had to replace EF in a project?

    • @buildingphase9712
      @buildingphase9712 2 года назад

      @@williambaker3961 Many times l have had to switch from EF to something like Dapper for performance improvements and use both at times. It all comes down to what your team is comfortable with, its art. No wrong or right way with it just trade offs.

  • @guy6311
    @guy6311 2 года назад +2

    To prevent crossing boundaries use DisableTransitiveProjectReferences

  • @satishbhuktar2020
    @satishbhuktar2020 Год назад +1

    Hey Nick, you earn a subscriber, this is really one of the topic who never talks, I also struggled at my initial phases of carrer why that domain is there, what is this Infra and all. but thanks to you. nice clarification.

  • @junaid_aslam
    @junaid_aslam 2 года назад +1

    Please make a video on best practices in Entity Framework. What mistakes do people usually make and what practices should be avoided? Please. Great videos!!

  • @gerardoverrone4902
    @gerardoverrone4902 2 года назад +8

    Hi Nick!! This architecture looks pretty clear in terms of separation concerns, abstractions, implementation logic, repositories and the division of Unit Tests layers. I'm following your From Zero to Hero courses related to dependency injection and Unit Test and both are amazing!!!
    I love the way you teach and would be amazing to count with one more course from you, entitle "From Zero to Hero Clean Architecture" course. I know it is a long topic to cover, but there are not many good courses on this topic. From my point of view if the course covers the architecture with the Mediator/CQRS patter it will be great but as I do not use that pattern, yet I would love to see the option without it too. The same goes on for EF with and without it, as I know you have plenty of followers not using it at all.
    It might also help a lot to have a starting module where you expose us on the Solid principles with examples, as most of the things this architecture is based on reflects on those principles. With all that you will deliver the best ever course on a software architecture that you have proven to work for a long time on big projects. Thanks a lot for the journey and the amazing mentoring!!!

    • @philliphaydon7017
      @philliphaydon7017 2 года назад

      Ah repositories, the worst pattern ever created. Misused everywhere.

  • @iandrake4683
    @iandrake4683 3 года назад +29

    First, thanks for making great content in short length video formats. No one seems to do that.
    Second, and forgive me here, but I'm just not a fan of DI everywhere architectures. The sales pitch rarely matches the real life experience.
    For example, your application layer interface uses the DBSet type, which is specifically an EF construct. So, no, I don't think you can just swap your EF implementation for another without updating the interface...which negates the value proposition.
    This is so often the case. In my 20+ years as a consultant, I've never been asked to switch backends, but I've worked on several systems that were built with that scenario in mind, and it's a maintenance nightmare.
    The most likely outcome for all software is that it will exist largely in its current form until it is replaced. So I typically build for simplicity of understanding, instead of magical redirection for an implementation swap that will never happen.

    • @nickchapsas
      @nickchapsas  3 года назад +6

      The usage of EF in the example template is very unfortunate because it is a thing I don't align with but it saved time from recreating the solution without it. That being said, I've been through a transition period from Azure to AWS in my experience as an engineers and by implementing the exact structure and abstractions I was able to move from Cosmos DB to DynamoDB and from Azure Service Bus to SQS extremely easily. That of course is only one time in my 5 years doing this professionally but it did come in handy.

    • @iandrake4683
      @iandrake4683 3 года назад +3

      @@nickchapsas it might be unfortunate, but I can't fault you for it.
      I'm not even sure how you'd fix it without a massive amount of code to either abstract it or add interface method for every data operation.
      One thing I do, at the bottom most layer for data access, I always use the MS ADO interfaces instead of directly using sqlclient classes. Then I can swap out that implementation for another one or create an implementation for a new backend store.

    • @iandrake4683
      @iandrake4683 3 года назад +1

      @Nickolai Paromov 100% agree.
      Horror story from the field: a client had an asp.net mvc app with DI everywhere on the constructors. In many cases there where stateful classes that required new instances for DI (not Singleton). So, for even very simple requests DI injection was creating up to 450 various class instances (because DI has a spidering effect), while the request needed/used none of them.
      It's an extreme example, but not only was that seriously slow, but every update to a method signature required an interface change, implementation change, and test change (that tests nothing).

    • @eparizzi
      @eparizzi 3 года назад +8

      ​@@iandrake4683 I can't fully agree with you on this. The fact that you had a client with an ASP.NET MVC app that was injecting 450 classes that the request wasn't using is simply a result of a bad design. If your constructors starts to receive too many dependencies that's a clear break of the SRP and has nothing to do with DI or Clean Architecture.
      Also, I don't think that extracting an interface from each class service implementation adds "additional complexity". To me, this "added complexity" is negligible compared to the benefits of having a clear interface for each service that allows me to easily swap implementations and simpler testing.
      In my +15 years of experience I had to refactor backend code, modernize it, swap implementations and I encountered the two sides of the coin: depending on implementations which made refactoring a lot more time consuming and depending on interfaces which made it way faster and easier.
      Maybe in your 20 years you worked for really big enterprise companies that usually never care or have the time to work on their technical debt and if they have an ASP.NET WebForms project you just have to stick with it. But in more fast-paced companies, startups, switching implementations and/or external dependencies is not that uncommon and DI does help you with it.
      But still, I do agree that in this case the use of EF is not very fortunate.

    • @iandrake4683
      @iandrake4683 3 года назад +1

      @@eparizzi Experiences often do vary and I think you described my clients well.
      One thing I should clear up, the client I was referring to thinks their DI implementation is good. They don't see a problem with it.
      To me DI is a modern day goto statement. Perhaps goto is a good feature, but it was most often misused and it became hated.
      I'm also not a fan of TDD. It's mostly nonsense dogma that takes a few obviously good ideas and then applies it to everything. To me, justifying DI for testing creates more problems than is solves. Again, this is only my experience with enterprise apps. Perhaps if I was working on an autopilot for passenger planes it would be a better use case. But as it is, most unit tests I see make me want to gouged my eyes out.

  • @filteredCode
    @filteredCode 3 года назад +6

    Firstly Nick, you've found a sweet spot in most of your videos. Just long enough to really get to the meat of a topic, but short enough not to drag it out. I'm really grateful for these videos!
    Secondly, a question if I may. I personally am a fan of structuring projects around the business domain as the primary rather than technical (e.g. calling your project WeatherForecast rather than having just having a folder WeatherForecast). Early on this may feel a bit unnecessary, but as a project grows I've found it much easier to maintain.
    My concern is from some of my experience is that with lots of devs on a project certain classes, services or entities (anything really) get created just a little too generic and then shared across domains (which is easy to do as they're all in the same project). Overtime SOLID principles get lost as things get refactored and these wonderful generic objects now do stuff not everyone cares about anymore. IMO keeping business domain as primary makes it easier to keep things separate even though it looks and smells similar to that of on object in another domain.
    So my question, in your opinion, how would you split (if at all) this project, assuming you start making big bucks with it it really takes off (think lots more developers, multiple teams maintaining certain domains etc.) Would this be a reasonable transition?
    WeatherForecast.Application
    WeatherForecast.Domain
    WeatherForecast.Infrastructure
    WeatherForecast.WebUI
    ....
    TodoList.Application
    TodoList.Domain
    ....

    • @nickchapsas
      @nickchapsas  3 года назад +1

      This "vertical slice" approach is also totally fine. It really comes down to what works better for a team in my opinion. I've seen logical domain grouping, either as a folder or as a project, to work really well.

  • @sarbjeet7
    @sarbjeet7 2 года назад

    Only video that help me understand infrastructure layer practically👍🏻👍🏻

  • @vladmartian
    @vladmartian 3 года назад +4

    In a Blazor Application (WebAssembly) the WebUI will be composed of 3 projects by default. Should you make a folder? Presumably yes. How about the Shared project, in which we define objects that are common between the two other projects. Should we drop the Shared folder? Then we will have to repeat the same code in both projects.

  • @rvkrasyl
    @rvkrasyl 2 года назад

    Круте відео, дуже дякую за пояснення

  • @abdelhaleemalfreihat7261
    @abdelhaleemalfreihat7261 3 года назад +3

    that's what I was looking for, keep going great content

  • @totenkorpf
    @totenkorpf 2 года назад +1

    Clean architecture and clean explication! Thanks you!

  • @justwatching6118
    @justwatching6118 2 года назад

    Thank you Nick for this and other videos!
    And also thank you other ones for commenting additional tips/advises!
    ❤❤❤

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

    07:44 - в application только интерфейс, а реализация в infruscructure, чтобы потом можно было легко подменять реализацию не меняя application
    09:19 - единственная причина почему Presentation зависит от infruscructure - чтобы регистрировать сервисы

  • @paramjotsingh4019
    @paramjotsingh4019 9 месяцев назад

    This was the EXACT video... I was looking out for!!

  • @manofqwerty
    @manofqwerty Год назад +2

    Would an API be considered a presentation layer in this instance?

  • @ДенисДоскач-д4п
    @ДенисДоскач-д4п 3 года назад +4

    Hi Nick. Thanks for the video! However, I am wondering why IApplicationDbContext interface contains DbSet properties, as they are part of infrastructure (entity framework)

    • @nickchapsas
      @nickchapsas  3 года назад +4

      I mentioned that in the pinned comment. Jason has chosen to couple himself with EF. I am not a fan of EF or his approach on this particular example so I kinda picked the wrong interface to demonstrate as an example. Ideally you don’t wanna hard couple yourself with tech such as EF unless you know what you’re committing to

    • @ДенисДоскач-д4п
      @ДенисДоскач-д4п 3 года назад

      @@nickchapsas Thanks!

    • @magic4218
      @magic4218 3 года назад

      @@nickchapsas would a better example be to have a repository interface in the Application project and the the implementation in the Infrastructure project?

  • @mattaku9430
    @mattaku9430 Год назад

    Man, that's perfect, that's how i did it as well without even seeing your project.

  • @AlexGoris
    @AlexGoris 3 года назад

    Thanks for this great video! I have looked at this project structure before, but what didn't sit well with me is the Infrastructure project, because I typically also write infrastructure-as-code for any application I create. There could be terraform scripts, kubernetes manifests etc which set up the actual infrastructure that needs to run the application. Since I don't want to have have 2 'Infrastructure' folders in my projects, I resorted to naming what is called 'Infrastructure' in this video, "Persistence". That is also not perfect since you're not always dealing exclusively with persistence in this project, but it worked for me so far.

    • @nickchapsas
      @nickchapsas  3 года назад +1

      The infra project has nothing to do with iac. That’s a separate thing

    • @AlexGoris
      @AlexGoris 3 года назад

      @@nickchapsas Yes I know, but they can both be named 'Infrastructure', and it feels bad practice to have 2 'Infrastructure' folders inside the project structure, so I was asking how other people adopt this structure, and also keep their IAC files stored in the same repository

    • @nickchapsas
      @nickchapsas  3 года назад +1

      @@AlexGoris Many things are called infrastructure. What if you're working on a civil engineering project? You gonna have tons of things called infrastructure. You cannot reserve a word, especially for a concept that came in after the popularizaiton of clean architecture. Infrastructure is a perfect name for the project. It is the Instrastructure of your application on a software architecture level.

    • @AlexGoris
      @AlexGoris 3 года назад

      @@nickchapsas that's a good point, I'll give it a try having 2 infrastructure folders in the structure. Thanks for your feedback!

    • @nickchapsas
      @nickchapsas  3 года назад +1

      @@AlexGoris No problem. As always, critical thinking is key. You can totally rename the project to anything that really works for you. It is just commonly accepted that we call it infrastructure but if in your case it causes confusion then an alternative would be also good as long as it makes sense in the context of your project.

  • @juancarlostorrescuervo5550
    @juancarlostorrescuervo5550 2 года назад

    I just stumbled upon this video and it is great, I have been using this approach for a while now and I find it great. Only in the case of api applications I recently started using the minimal api approach that came with net 6. The WebUi project is much simpler this way.

  • @satishbhuktar2020
    @satishbhuktar2020 Год назад +1

    Hey @nickchapsas I like this structure but can we use this in each Microservice?

  • @nicktech2152
    @nicktech2152 3 года назад +4

    Nick, can you explain, how would you swap your EF with cosmos Db if inside IApplicationDbContext you have direct dependency on a DbSet? Aren’t DbSet classes defined in the EF Library? Would you easily swap the provider without breaking the Interface?

    • @drm1983
      @drm1983 3 года назад

      Just set as return type something else , a Collection or a List. DbSet implements all these:
      IQueryable, IEnumerable, IEnumerable, IQueryable, IAsyncEnumerable, IInfrastructure, IListSource

    • @nicktech2152
      @nicktech2152 3 года назад +1

      @@drm1983 Thats not a solution at all :)

    • @ib0018
      @ib0018 2 года назад

      I think he meant you can swap the db INSIDE ef. Not with ef. Ef can handle cosmos db as well.

  • @KristherLouisVidal
    @KristherLouisVidal 2 года назад

    This is why I love to learn more about c# and .net because you can get as flexible as you want. Unlike other frameworks where you are tied to a certain convention.

  • @iliyanyankov7401
    @iliyanyankov7401 Год назад

    Very well explained, Thank you !

  • @krrishkole
    @krrishkole 3 года назад +4

    Hi Nick, great video. What is your view on vertical slicing architecture?

  • @PaulSebastianM
    @PaulSebastianM 3 года назад +44

    Careful guys. This explanation might be construed towards implementing an Anemic Domain. For example it is advocating for implementing all domain logic in the application layer. Domain shouldn't be quite as simple as he promotes. That's called an anemic model.

    • @BattleCheese2
      @BattleCheese2 2 года назад +14

      Agree. Structuring your application to suit the domain is the way to go. Not all domains are equal, some require drastically different solutions. Folder names/namespaces like "Entities" or "Exceptions" are usually a sign of poorly designed code, in my experience. Having technical names scattered all over makes for technical splitting, whereas things should be split by domain function to avoid crazy dependency graphs and difficult refactoring when technology inevitably changes five years down the road...

    • @invictuz4803
      @invictuz4803 2 года назад +14

      Thanks for the disclaimer, these kind of contradictions made me give up on learning clean architecture.

    • @xO_ADX_Ox
      @xO_ADX_Ox 2 года назад +5

      Sir. How do I structure a Project in C# the right way?

    • @belvss896
      @belvss896 2 года назад +12

      I'm pretty much on the same ground as @InvictuZ. Everyone says different things about the same topics. Can you guys provide examples? Thanks!

    • @Dpaz2009
      @Dpaz2009 Год назад

      ​@@belvss896look at a course by Vladimir khorikov refactoring away from an anemic domain model towards a rich one. Khorikov has tons of examples

  • @ChristeddyParapat1
    @ChristeddyParapat1 3 года назад

    Wow, that's awesome approach..

  • @guilderw
    @guilderw 3 года назад +2

    Can this design be described as follows:
    Domain: The what
    Application: The How
    Infrastructure: Server-side when
    Presentation: Client-Side when

  • @wh33lers
    @wh33lers 2 года назад

    thanks for sharing. Very helpful and a good starting point

  • @pilotboba
    @pilotboba 3 года назад +2

    I'm assuming if your UI is an MVC project your view models would still be defined in the Presentation layer, since it is a concern only for that layer?
    Where are you putting your business rules/validation logic? In the application layer or the domain layer?

    • @temp50
      @temp50 3 года назад

      DTOs, etc..

  • @ayedabboushi7221
    @ayedabboushi7221 3 года назад

    Thanks for sharing your knowledge.

  • @LewisCowles
    @LewisCowles 3 года назад

    Very interesting take on the clean architecture Nick. I Love that you gave context for this, including 3 years and how you would manage various parts. I Think the presentation should not be the entrypoint, but instead application, so you don't need internal to stop people using infrastructure. The other way to do this is to have another layer, could call it integration, and it would use both presentation and infrastructure and application as internal.

  • @PyaePhyoAung-xi9fh
    @PyaePhyoAung-xi9fh 3 года назад

    Short and clear explanation. Thank you, sir.

  • @asdasddas100
    @asdasddas100 3 года назад +1

    This is what I needed badly

  • @pratiks6576
    @pratiks6576 3 года назад

    This is pure gold !

  • @sunnypatel1045
    @sunnypatel1045 3 года назад

    Good work Nick. When it comes to DDD and Clean Architecture I love this setup! I do have another layer for cross cutting or can setup modules for each layer for DI if needed. Keep up the good work pal!

  • @clearlyunwell
    @clearlyunwell 3 года назад

    So application layer is interfaces, infrastructure layer is the implementation of those interfaces, models are separate and UI uses DI and interfaces from the application layer, and models. I’m itching to change my projects now 😋

  • @danielblanquez
    @danielblanquez 3 года назад +1

    @NickChapsas How do you share the Domain across multiple solutions.
    Let say you have another different solution with a different scope but with common classes with the solution exposed in the video.
    do you recreate those clases in the other application domain? Nuget package?

    • @nickchapsas
      @nickchapsas  3 года назад +1

      Domain is split by domain concerns. It is usually a centralized project that is shared as a nuget package

  • @being_aslam_tiger
    @being_aslam_tiger 2 года назад

    Thanks for the video.

  • @wolfganghaeussler
    @wolfganghaeussler Год назад

    Hey Nick,
    at 12:53 you mention putting contracts and SDK in a separate project.
    Would those live in the Web API or application layer?

  • @destroyonload3444
    @destroyonload3444 3 года назад

    This is near identical to my current structuring. It's very easy to learn, it's organized, and as you point out: easy to change things.

  • @flyingmadpakke
    @flyingmadpakke 3 года назад +2

    I was wondering if you, or someone in general, could recommend a good doc or web page which describe a standardized positioning scheme for all the different elements than can go into a class, interface etc.
    Like if I have my fields at the top, then props, then constructor and then methods, that is the basics of how I do it, but what if I have different access levels for my methods, modifiers, or less common elements?
    I.e. where does my Implicit type conversion operator go in relation to my protected abstract methods?

    • @nickchapsas
      @nickchapsas  3 года назад +3

      This is a really interesting topic and it’s a discussion I have with my team members from time to time. It’s heavily opinionated and I couldn’t come out with a video telling people what I prefer for such a niche thing. In my opinion, as long as you are consistent across your projects, whichever way you go about it is fine.

    • @flyingmadpakke
      @flyingmadpakke 3 года назад +1

      ​@@nickchapsas Ok, thanks, my major problem right now is that I'm not consistent at all yet :)
      Btw, I also saw your video on Async, but I have one more interesting question for you on that topic. The idea of recursive tasks.
      Method()
      {
      Task.Run(Method)
      }
      I've done a test with await and without it. As expected, when awaiting the memory grows rapidly as I suspect the method is waiting for the task to complete, but that task is waiting for its task to complete and so on...
      But without await, like shown above, they are all fire and forget. So while I run this in my main and wait like 10 sec. the memory usage is constant. But are there any potential problems with this?

  • @TheSiddhaartha
    @TheSiddhaartha 3 года назад

    This is a great video! This kinda information is provided only by people really working on project architecture.

  • @davidsantacruz7195
    @davidsantacruz7195 Год назад +1

    Hi Nick. What do you think about using the domain (entities, aggregates, enums, logic, etc.) into the Blazor WebAssembly client? Or we only can share DTOs between Backend and Frontend?

  • @zerosandones7547
    @zerosandones7547 2 года назад

    Where do we place our "Extensions" folder (to store our extension methods)? In 2:55 you said that in the Domain Layer: "things that are used across the whole domain" will be stored there. So I assume that the Extensions will be place there?

  • @propro8040
    @propro8040 Год назад

    this is so perfect, thank you ♥

  • @ivanz6368
    @ivanz6368 3 года назад

    I just stuff all in solution folder and it works!

  • @avinash6141
    @avinash6141 2 года назад

    Hi nick, whats the use of Events folder in the Domain? i see some dispatching base events at the DB Context Save changes method?
    whats the purpose of Events folder

  • @Tymonello
    @Tymonello Год назад

    A structure for other architectures would be useful too, because many beginners star with other projects, not CQRS and mediator. Maybe a clean acrhitecture with service-repository pattern, in an MVC or WebAPI would be useful to some learners as well.

  • @diopistacchio5037
    @diopistacchio5037 3 года назад +1

    Would be useful a video where you create all the layers and an unit test as an example(one project to create with who Watch the video). Anyway thx very much, you do the best video about architecture and the way to implement a software 😁✌️.

  • @katjejoek
    @katjejoek 3 года назад +3

    Thank you for all your videos! Question: would the video be different if your example were a WPF application instead of a web-application? Or does it only have a different presentation layer?

    • @shreyasjejurkar1233
      @shreyasjejurkar1233 3 года назад +1

      You can have different presentation layer using same Application layer!

  • @lobintsevvladislav5982
    @lobintsevvladislav5982 3 года назад +1

    Hey, thanks for the video. How do you think, what is the benefit of putting domain models in a separate assembly? So it is clear that for Web UI we don't want to depend on specific web framework. For Infrastructure as well, we don't want to depend on specific ORM, external services, etc. But what about domain? How this helps to archieve clean structure? One thing comes to my mind is that we can share this Domain lib project across different solutions. But this doesn't seem to be the best choise and even considered as antipattern (when you have Microservices architecture, follow DDD, etc.).

    • @pilotboba
      @pilotboba 2 года назад

      The idea of sharing the domain among different applications in your project is the reason. I am pretty sure Steve Smith's clean architecture project has a single "Core" project that contains what Jason puts in Domain and Application projects. YYMV.

  • @mohamedsalah324
    @mohamedsalah324 2 года назад

    Great work your videos are really helpful

  • @mana20
    @mana20 2 года назад

    when do you choose to use something like Mediatr or Brighter? what uses cases would use it and when would you not?

  • @christian.mar.garcia
    @christian.mar.garcia 3 года назад

    Great explanation. Keep up the good work.

  • @LonliLokli
    @LonliLokli 3 года назад

    Thanks for all your videos, even I cannot agree with all ideas of current one.
    1) Just to note, Rider already have project diagram tool, so it might be useful to show this during the talk.
    2) I do not like MediatR approach, but will comment in separate video later
    3) There is toouch coupling to the actual infrastructure. Imagine you will try to change from EF to Mongo storage, now your project will have to reference multiple stores just because of folder design
    4) I do not see profit in tests and src folders - they make sense only in Solution view, not on File system.

    • @nickchapsas
      @nickchapsas  3 года назад +1

      1) Yeah I remembered about this one after I shot the video
      2) That comes down to personal preferences
      3) The implementations in the infrastructure is the only thing you need to change if the abstractions in application are done correctly
      4) Solution folders can actually be both. If you create them in the file system then the solution will link them as actual folders.

  • @mbalaganskiy
    @mbalaganskiy 3 года назад +3

    I've seen an argument regarding changing orm a dozen of times, and never actually seen any real examples of that. Going from ms SQL to cosmos, changing the context will be the least of the problems a developer will face IMO

    • @alissoncandatem1896
      @alissoncandatem1896 2 года назад

      Ok but what if you want to use two orm's? Let's say i'll use Dapper (wich is a micro orm) and nhibernate(only to write things to the database)? Wouldn't this level of abstraction be better in that situation?

    • @mbalaganskiy
      @mbalaganskiy 2 года назад

      @@alissoncandatem1896 this is not common at all, an average project will hardly have this complexity

  • @ivandrofly
    @ivandrofly 2 года назад

    9:15 Presentation layer dependency

  • @tehsimo
    @tehsimo 2 года назад

    I signed up for Patreon but cannot find the src for this in your github repo? is there a specific name I should look for?

  • @szdan2k
    @szdan2k 3 года назад +1

    It's quite good separation. Thanks. :)
    - It seems that it's an upgrade for the good old 3-layer architcture, the difference is that the Business Logic Layer is separated into 3 layers and the data access is part of one of the business layers. :)
    ~PresentationLayer
    ~BLL.Application
    ~BLL.Infrastructure (contains DataAccessLayer too)
    ~BLL.Domain
    - BUT persistence should be in it's own layer.
    Why do you mix persistence with business logic in Infrastructure project? I see those are in different folders, but still they are in the same project.
    You should separate those for the same reason you separated abstractions from implementation: If you have to change persistence, you don't have to change the project which contains the business logic and vice-versa.
    If the reason for that is that you use EF, we can't do much in this case. I don't like EF and LinqToSql because it makes you to mix the business and data access layers.
    - The name "Infrastructure" for the "implementation" layer is a little bit misleading. First i thought it's a purely technical project, where you hold everything which is independant of the domain and the business logic, until you said it holds the implementations. Another name would be better.
    - And with that said, i would create another project just for the technical things - enum-string-int converters, generic object-to-object mapping, string helpers...etc - and anything which can be used in any project regardless of the domain.
    I would go even further, and if you can make this technical project general enough, you can refer it in other appliations. Maybe the best option is to make a nuget package from it.
    Have a great day!

    • @pilotboba
      @pilotboba 2 года назад

      >Why do you mix persistence with business logic in Infrastructure project?
      There is no business logic in the Infrastructure project. I suggest you spin up a project with Jason's template and look through it, step debug through some of the requests/commands.

  • @corblimey8729
    @corblimey8729 Год назад

    Further more...You have the WebUI dependent on the Infrastructure layer, which is not ideal, better to put those interfaces for services it needs to register in the 'Definitions' projects I mentioned in my previous comment. As previously stated, the 'Definitions' project has all (independent) types, interfaces and enums, and the project must have no dependencies. (there may be some interfaces or types which will require a dependency, and they will have to be defined elsewhere)

  • @abracadabra544
    @abracadabra544 Год назад

    How to fix the "Infrastructure layer reference to Presentation layer" just for dependency resolution (!!) is that I used to create a separate class library called "ProjectName.DependencyResolution" which would have all the referecens to all the projects (except PResentaiton) and then PResentaion would refer only DependencyREsolution and the service collection extension methods are defined in DependencyResolution. In this way you really isolate the infrastructure implementations from the Presentation layer (albeit after NET core the references are cascaded but nothing we can do about that I think)

  • @noble_mickmick8889
    @noble_mickmick8889 11 месяцев назад

    Thank you I love it, any examples on a website or downloadable?

  • @kamaatakhify
    @kamaatakhify 3 года назад

    Great videos, keep it up!!!

  • @fandermill
    @fandermill 2 года назад

    I like creating a separate Bootstrapper project that does the tying up in de IoC container, so I can prevent referencing Infrastructure from the presentation layer directly.

  • @microtech2448
    @microtech2448 Год назад

    Hi, can you please confirm where ef core entities and their save get methods would go?
    Another thing, is it possible to configure project somehow that WebUI does not need to reference Infrastructure project?

  • @maartenvissers1770
    @maartenvissers1770 3 года назад

    Is their an example of cleanarchitecture with a seperate api project for contracts? To understand it better.

  • @NorbertHaberl
    @NorbertHaberl 2 года назад

    Hi, why is IApplicationDbContext in App Layer and not defined in Core ?
    How would you deal with ValidationServices in Core layer which check for integrity or something outside the boundary ?

  • @peternimmo74
    @peternimmo74 Год назад

    You touched on Gherkin tests, at work whenever this is talked about it's always in relation to QAs, rather than Devs, do you have any videos on Gherkin when used by developers?

  • @marcusmaunula5018
    @marcusmaunula5018 3 года назад +3

    Gil Cleeren has a course on PS on this. He uses Blazor though :).

  • @corblimey8729
    @corblimey8729 Год назад

    Hi Nick, I have a problem with the idea that the Infrastructure project needs a reference to the Application (to get IApplicationDBContext). For years I've used MS Architecture Framework guide idea of a separate 'Definitions' project for types, interfaces and enums (no project refs allowed). Doing that way puts IApplicationDBContext in 'Definitions' project and avoids Infrastructure ref to Application project. (One can always create a separate folder in 'Definitions' for Domain objects).

  • @RainOrigami
    @RainOrigami 2 года назад

    hello nick, do you have a video that expands on this for customising an application for multiple different customers? how would you extend the domain without having to change the core domain project so that updates in the original domain can be merged into the customer domain without any large conflicts?
    this is always a problem of mine to wrap my head around, as most project structures are not inherently made to handle multiple different customisations for customers. like a finance application that has a core application but customer A needs additional things, customer B has a different workflow for a certain thing, customer C needs to import data from a third party system, but those things are not supposed to become part of the core application.

  • @jannickbreunis
    @jannickbreunis 3 года назад +1

    I'm wondering, what does the word 'common' mean? I see it with purchased software dll's, this video and some other projects.

    • @buriedstpatrick2294
      @buriedstpatrick2294 3 года назад +1

      It's usually used for libraries shared across the solution. It's a potential code smell if abused.
      For instance, if you have two APIs using some similar setup code, it CAN make sense to make it more DRY by adding a common API-library.
      Like:
      MyProject.Sales.Api
      MyProject.Products.Api
      Both depending on:
      MyProject.Api.Common
      But I personally usually steer away from using "Common" as it doesn't really add any useful information other than the fact that some projects are using it, in my opinion.

  • @linap972
    @linap972 2 года назад

    Hi Nick, great video, but raised some question. I was under assumptions that publish done on project level - What if i need to Publish all those projects in 1 folder, how it will done? Thanks

  • @mccarthyjonathan69
    @mccarthyjonathan69 2 года назад

    For the presentation layer what about data seeding should the presentation layer not implement a abstraction of creating basic config related data for the database?

  • @sps014
    @sps014 3 года назад

    Awesome stuff

  • @jfpinero
    @jfpinero 3 года назад

    At work we have a solution folder for our pipeline stuff (and docker file - the kubernetes chart can be found when switching views to file)

  • @chaouanabil3087
    @chaouanabil3087 2 года назад

    thank you nick for this video. what do you think about abp framework as a starting template for clean architecture and DDD.

  • @GeorgeMiscalencu
    @GeorgeMiscalencu Год назад

    Nice video @nickchapsas! How about domain services, not infrastructure services? I am referring to services containing business logic and different manipulations of you domain data (domain data extracted by your infrastructure services). Is it OK to have these implementations in the Application project?

  • @adrianleon4396
    @adrianleon4396 2 года назад

    Hey, thanks so much for the video.
    I wanted to ask, what do you think about having DbSet in the application layer (EF dependency)? As EF is implementation specific shouldn't it be in the Infrastructure layer?

    • @vladtoma9848
      @vladtoma9848 2 года назад +1

      TBH, i have exactly the same questions.
      I find so many opinions on this template and infrastructure that is very hard to tell. So I would say this:
      As long as you respect the dependency flow and you keep your domain simple is ok.
      Just as a reference I keep the dbcontext in infrastructure and using repository pattern. Then the interfaces for repos I’m placing them in domain. It is not ideal but do the work.

  • @shustypl
    @shustypl 3 года назад +1

    I, like many authorities, do not entirely agree with Jason Taylor's approach. I believe that when using Clean Architecture in the application layer there should be no dependency on Entity Framework. Only the infrastructure layer should use EF. Some also use EF in the domain layer, which I completely disagree with and think that the domain layer shouldn't depend on anything, especially external libraries like EF.

    • @nickchapsas
      @nickchapsas  3 года назад

      I should make the displaimer in the beginning of the video clearer that I do not agree with the use of EF at all but I am using the project because I couldn't be arsed remaking it without EF for this demo.

    • @shustypl
      @shustypl 3 года назад

      @@nickchapsas I often use EF in Clean Architecture, but I always keep its implementation in the infrastructure layer. I am very good at testing repositories where I am using EF. The ability to use context in-memory is great for unit testing. lthough I prefer to split the application for commands where I often use EF, and for query with other libraries, especially when you set up a separate optimized, most often denormalized read-only database. Especially when I use event sourcing. EF isn't all that bad, and it often gives a lot of benefits, but I just don't agree with the way he puts into Jason Taylor in Clean Architecture.

  • @oldwhitowl
    @oldwhitowl 3 года назад +1

    Hi Nick, I love the videos, they are so helpful! Could I pick your brains on using dapper with clean architecture. I guess I'm right in thinking dapper should live within the infrastructure project? It'd be neat to have a generic dapper class but i can't see how this would work without the Application layer having knowledge of the database structure, passing in tables or stored procedure names. So would it be reasonable to have a class per model (repository?) with associated query/commands or one class per query/command (CQRS) with which to perform dapper commands?
    Another question I have is regarding MediatR. In this architecture would you have the request call in the Client/API controller and the handler in the Application? Any help really appreciated!

  • @andriizahr448
    @andriizahr448 3 года назад +1

    Is it a common practise to use microservies architecture with this 'clean architecture' approach for each microservice?

    • @nickchapsas
      @nickchapsas  3 года назад +3

      This is how I am working yes

  • @SrinidhiS-t7r
    @SrinidhiS-t7r Год назад

    is this only for single page applications because jason taylor clean code architecture is mentioned for single page application on their github repository

  • @xtazyxxx3487
    @xtazyxxx3487 2 года назад

    How can microservices implemented on that? Different solution for different services or different application layer project?

  • @Rajeshsingh-ws5th
    @Rajeshsingh-ws5th 3 года назад +1

    Hi Great video, have seen lot of solutions with test projects in it, can't we should keep unit test project in separate solution ?

    • @nickchapsas
      @nickchapsas  3 года назад

      Test projects should be in the same solution with the project they are testing but in a different solution folder.

    • @Rajeshsingh-ws5th
      @Rajeshsingh-ws5th 3 года назад

      @@nickchapsas Thanks, have some points, we have a big legacy application and most of the unit test things are deprecated in new version (like .accesser file) which has now big dependency while building after migrating into 2019. If we can separate it in other solution and handled by other team then building main solution will not be dependent and break. Your view pls thanks.

    • @pilotboba
      @pilotboba 3 года назад +1

      @@nickchapsas I used to use solution folders, but gave it up. I'd rather see.. Application and Application.Tests.XXX projects right next to each other in the Solution Explorer (or whatever structural viewing you have in your IDE/Editor of choice)