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

แชร์
ฝัง
  • เผยแพร่เมื่อ 16 ก.ย. 2024

ความคิดเห็น • 342

  • @nickchapsas
    @nickchapsas  3 ปีที่แล้ว +96

    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 ปีที่แล้ว +3

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

  • @shayvt
    @shayvt 3 ปีที่แล้ว +112

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

  • @Chiramisudo
    @Chiramisudo 3 ปีที่แล้ว +60

    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!

  • @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!

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

  • @thefarhadfarhadi
    @thefarhadfarhadi 11 หลายเดือนก่อน +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 6 หลายเดือนก่อน

      What was the book?

    • @stefano_schmidt
      @stefano_schmidt 6 หลายเดือนก่อน

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

  • @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 ปีที่แล้ว +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.

  • @gabriel.andreato
    @gabriel.andreato 29 วันที่ผ่านมา

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

  • @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 7 หลายเดือนก่อน

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

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

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

  • @guy6311
    @guy6311 2 ปีที่แล้ว +2

    To prevent crossing boundaries use DisableTransitiveProjectReferences

  • @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 ปีที่แล้ว

      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?

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

  • @karimpeymani6569
    @karimpeymani6569 ปีที่แล้ว +1

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

  • @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 ปีที่แล้ว

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

  • @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!!

  • @filteredCode
    @filteredCode 2 ปีที่แล้ว +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  2 ปีที่แล้ว +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.

  • @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

  • @sarbjeet7
    @sarbjeet7 2 ปีที่แล้ว

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

  • @abdelhaleemalfreihat7261
    @abdelhaleemalfreihat7261 3 ปีที่แล้ว +3

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

  • @justwatching6118
    @justwatching6118 2 ปีที่แล้ว

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

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

  • @totenkorpf
    @totenkorpf 2 ปีที่แล้ว +1

    Clean architecture and clean explication! Thanks you!

  • @rvkrasyl
    @rvkrasyl 2 ปีที่แล้ว

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

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

  • @paramjotsingh4019
    @paramjotsingh4019 6 หลายเดือนก่อน

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

  • @PaulSebastianM
    @PaulSebastianM 3 ปีที่แล้ว +43

    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 11 หลายเดือนก่อน

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

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

  • @AlexGoris
    @AlexGoris 2 ปีที่แล้ว

    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  2 ปีที่แล้ว +1

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

    • @AlexGoris
      @AlexGoris 2 ปีที่แล้ว

      @@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  2 ปีที่แล้ว +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 2 ปีที่แล้ว

      @@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  2 ปีที่แล้ว +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.

  • @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 😁✌️.

  • @PyaePhyoAung-xi9fh
    @PyaePhyoAung-xi9fh 3 ปีที่แล้ว

    Short and clear explanation. Thank you, sir.

  • @TheSiddhaartha
    @TheSiddhaartha 3 ปีที่แล้ว

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

  • @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!

  • @asdasddas100
    @asdasddas100 3 ปีที่แล้ว +1

    This is what I needed badly

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

  • @manofqwerty
    @manofqwerty ปีที่แล้ว +2

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

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

  • @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 😋

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

  • @mbalaganskiy
    @mbalaganskiy 2 ปีที่แล้ว +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

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

  • @Computerix
    @Computerix 3 ปีที่แล้ว +2

    Loving these topics ! can you do authentication and authorization next? Or pagination too would be really helpful

  • @mattaku9430
    @mattaku9430 ปีที่แล้ว

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

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

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

  • @ДенисДоскач-д4п
    @ДенисДоскач-д4п 3 ปีที่แล้ว +3

    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 ปีที่แล้ว +3

      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 2 ปีที่แล้ว

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

  • @wh33lers
    @wh33lers 2 ปีที่แล้ว

    thanks for sharing. Very helpful and a good starting point

  • @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

  • @ayedabboushi7221
    @ayedabboushi7221 2 ปีที่แล้ว

    Thanks for sharing your knowledge.

  • @iliyanyankov7401
    @iliyanyankov7401 ปีที่แล้ว

    Very well explained, Thank you !

  • @krrishkole
    @krrishkole 3 ปีที่แล้ว +4

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

  • @ChristeddyParapat1
    @ChristeddyParapat1 3 ปีที่แล้ว

    Wow, that's awesome approach..

  • @pratiks6576
    @pratiks6576 3 ปีที่แล้ว

    This is pure gold !

  • @christian.mar.garcia
    @christian.mar.garcia 3 ปีที่แล้ว

    Great explanation. Keep up the good work.

  • @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)

  • @fandermill
    @fandermill ปีที่แล้ว

    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.

  • @propro8040
    @propro8040 ปีที่แล้ว

    this is so perfect, thank you ♥

  • @marcusmaunula5018
    @marcusmaunula5018 3 ปีที่แล้ว +3

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

  • @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)

  • @ivanz6368
    @ivanz6368 3 ปีที่แล้ว

    I just stuff all in solution folder and it works!

  • @Imploser
    @Imploser 2 ปีที่แล้ว

    You can add ServiceCollectionExtensions to every layer and call it hierarchically. So, there is no need to direct reference to Infrastructure layer from Presentation layer. Maybe that time the architecture transforms into onion architecture :) And also; i don't understand why application layer needs integration tests. I prefer writing integration tests by application instance layers such as api, consumer or job. So it could cover more code.

    • @RoyZASTEROiD
      @RoyZASTEROiD ปีที่แล้ว

      @Imploser can you please explain "ServiceCollectionExtensions" approach in more easy to understand language or in plain english/language for juniors? if possible with example please, or if u give me some blog post i can read from that post. Thanks

  • @Alex-fj2xu
    @Alex-fj2xu 11 หลายเดือนก่อน

    Looks great except probably the Application layer dependency on EF (DbSet).

  • @mohamedsalah324
    @mohamedsalah324 2 ปีที่แล้ว

    Great work your videos are really helpful

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

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

  • @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

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

  • @being_aslam_tiger
    @being_aslam_tiger 2 ปีที่แล้ว

    Thanks for the video.

  • @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)

  • @itaccount1993
    @itaccount1993 8 ชั่วโมงที่ผ่านมา

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

  • @MrSabujsen
    @MrSabujsen 3 ปีที่แล้ว

    It great, but using context, service layer also good aproach. look simple also

  • @kamaatakhify
    @kamaatakhify 3 ปีที่แล้ว

    Great videos, keep it up!!!

  • @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!

  • @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?

  • @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?

  • @propro8040
    @propro8040 ปีที่แล้ว

    Hi Nick, thank you for this video
    can you make a video about Blazor also?

  • @julienlefevre1661
    @julienlefevre1661 ปีที่แล้ว

    Hi :) thanks for the video. "UI should not refer to infrastructure elsewhere than the startup". Sure! Why not creating a IServiceCollection extension in the application layer that configure the infrastructure services registration? Thus you only have to refer to application. In your video why don't you call "AddInfrastructure" from application layer?

  • @hcerim
    @hcerim 3 ปีที่แล้ว +8

    Having commodity-specific stuff like MediatR and EF in the Application layer is weird. You should always tend to abstract away external providers as much as possible. Here, if you decide to switch to some database that does not have EF API (or may wish to integrate the nosql database instead) your app will break which should not be the case in a properly decoupled app.

    • @nickchapsas
      @nickchapsas  3 ปีที่แล้ว +1

      This is the reason why I didn't actually dive into the tech and focused only on the layers and the organization stuff. MediatR and EF (especially EF) is opinionated tech which might not be everyone's cup of tea. The idea behind the separation and the layering though is still strong even if you don't use MediatR and EF which is why I didn't mention them.

    • @hcerim
      @hcerim 3 ปีที่แล้ว +8

      @@nickchapsas Your explanation of the architecture is completely fine but the project template itself is full of these coupling mistakes. Maybe it was worth mentioning that, especially because of the newcomers who may feel like it is a good approach (e.g. exposing the IQueryable in the Application layer instead of the IEnumerable).

    • @invictuz4803
      @invictuz4803 2 ปีที่แล้ว +1

      @@hcerim True, attempting to introduce a concept as complex as architecture without "going into the details" or at least having disclaimers that the high level details might be misleading is the worst thing for the audience. I spent two weeks trying to learn clean architecture and confused by contradiction upon contradiction with all the different articles trying to introduce this at a high level and the articles that go into the details. After two weeks, I just gave up as there were too many contradictions.

  • @caillinspain5822
    @caillinspain5822 2 ปีที่แล้ว

    This seems to be the opposite of vertical slice architecture style solution layout, where you layout your solution by grouping code by business features and functionality...

  • @fishzebra
    @fishzebra 3 ปีที่แล้ว

    Shouldn't Commands be in the domain layer and not application as they can contain domain logic such as authorisation etc? They can just depend on repository interfaces in infrastructure.
    A seperate Composistion Route project can also be created to prevent the need for the UI project knowing about the Infrastrucure layer.
    Thanks for a great demo

  • @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!

  • @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?

  • @yp5387
    @yp5387 3 ปีที่แล้ว +2

    This is exactly what I need. I hate that Microsoft documentation directly shows code examples inside the class and doesn't tell us where should it resides in the actual project library.

  • @noble_mickmick8889
    @noble_mickmick8889 8 หลายเดือนก่อน

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

  • @tajayeb
    @tajayeb 3 ปีที่แล้ว

    Many thanks for this explanation. Is there a video with a micro services based project layout?

  • @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?

  • @skidrow406
    @skidrow406 3 ปีที่แล้ว

    great, thanks

  • @sps014
    @sps014 3 ปีที่แล้ว

    Awesome stuff

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

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

  • @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?

  • @pepperparkffm
    @pepperparkffm ปีที่แล้ว

    I don't understand why developers nearly always split their application layers into separate projects, and therefor a PHYSICAL separation. Theres no need for it except you want to share one part or, in very rare and crazy situations, you want to change a layer on-the-fly without having to rebuild and deploy your app. Beside this, still too much dependencies in my personal opinion. However, I really like your videos! 🙂

  • @PaulPaulPaulson
    @PaulPaulPaulson 3 ปีที่แล้ว

    I used to code in SmallTalk for some years and miss how it handles modularity. I always wonder why other languages don't do it in a similar way. Using projects for the modular structure just isn't the same.

  • @RainOrigami
    @RainOrigami ปีที่แล้ว

    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.

  • @mrharc
    @mrharc 3 ปีที่แล้ว

    Where would I put the database calls, the queries. In infrastructure layer then the interface would be in application layer.
    The paths would be somthing like this (UI / API controller) GetAllItems -> (Application) Has method GetAllItems that has injected a DBContext, then it calls infrastructure -> (Infrastructure) SQL query to get all items?

  • @8bits292
    @8bits292 ปีที่แล้ว

    But if another application is to be created. Can the infrastructure layer be reused with that new application ? Because the services interface is defined in the application layer. So the infrastructure layer is not independent. It can't be reused with another application

  • @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).

  • @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