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.
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!
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.
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!
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.
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.
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.
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.
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
@@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.
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.
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?
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!
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 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
@@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
@@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
@@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!
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.
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.
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
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!!
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!!!
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.
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 ....
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.
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.
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?
@@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.
@@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.
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.
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 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
@@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 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.
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!
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?
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.
@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?
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.
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.
@@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.
@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).
@@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.
@@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.
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?
Just set as return type something else , a Collection or a List. DbSet implements all these: IQueryable, IEnumerable, IEnumerable, IQueryable, IAsyncEnumerable, IInfrastructure, IListSource
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.
Hi Nick. Thanks for the video! However, I am wondering why IApplicationDbContext interface contains DbSet properties, as they are part of infrastructure (entity framework)
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
@@nickchapsas would a better example be to have a repository interface in the Application project and the the implementation in the Infrastructure project?
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?
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 😁✌️.
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
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
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.
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?
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?
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)
is this only for single page applications because jason taylor clean code architecture is mentioned for single page application on their github repository
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?
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.
@@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?
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).
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?
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 ?
07:44 - в application только интерфейс, а реализация в infruscructure, чтобы потом можно было легко подменять реализацию не меняя application 09:19 - единственная причина почему Presentation зависит от infruscructure - чтобы регистрировать сервисы
Hello nick can you tell me how to scaffold an entity from the domain layer in the presentation layer but at the same time i cant add a reference of domain layer in the presentation layer due to n tier architecture design?
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.
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?
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.
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.
Lets say that I have a solution, for WebUI, prepared in that way. Now I want to create API that will be used by some external service - for example mobile app. How should I make it? Could I create a new project here - next WebUI, and it'll drive from Domain, App and Infrstructrue? What if I will want to prepare API nuget client that helps using API in external services? If I will do it in simmilar way it became huge and some implementation will be included but never used ;/ Could you please help me with that?
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)
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?
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.
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 😋
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.).
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.
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
On the issue of registering services in a function in the Infrastructure layer, but otherwise keeping everything in the Infrastructure internal: whenever I try that, the dependency injection breaks because it can't instantiate any of the classes that are internal to a separate project (ie: in the Infrastructure, not in the Presentation). How do you get around this?
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.
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...
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.
Idea is almost great :) Do you have github link with this sample to fork and modify smth?
@@LonliLokli The link to the project can be found in the description
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!
@@shreyasjejurkar1233 abstraction is required only for input and output types ie domain objects.
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.
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!
Can you please make a video on Unit Tests and Integration Tests architecture, best practices, etc.?
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.
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.
What was the book?
@@keipalamaybe the Clean Architecture (Robert C. Martin) itself
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.
Thanks Nick, This is very clear of explanation for architecture.
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.
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
@@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.
Amazing, I never had seen anyone showing in code this level of examples, thankse
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.
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?
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!
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 👍
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?
@@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
@@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
@@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
@@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!
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.
Only video that help me understand infrastructure layer practically👍🏻👍🏻
that's what I was looking for, keep going great content
Thank you Nick for this and other videos!
And also thank you other ones for commenting additional tips/advises!
❤❤❤
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.
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
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!!
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!!!
Ah repositories, the worst pattern ever created. Misused everywhere.
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.
In your example, the application layer will change if you changed databases because the return type DbSet is entity Framework specific
You can use different databases with Entity Framework
@@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
@@denipop83 If you move from relational to non-relational, your change is not just the data persistence abstraction, it's probably across ALL layers.
This was the EXACT video... I was looking out for!!
Would an API be considered a presentation layer in this instance?
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
....
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.
Clean architecture and clean explication! Thanks you!
This is a great video! This kinda information is provided only by people really working on project architecture.
To prevent crossing boundaries use DisableTransitiveProjectReferences
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.
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?
@@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.
@@buildingphase9712 Thank you for you explanation. Yes, this makes a lot more sense to me.
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?
@@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.
Круте відео, дуже дякую за пояснення
Short and clear explanation. Thank you, sir.
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.
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.
The infra project has nothing to do with iac. That’s a separate thing
@@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
@@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.
@@nickchapsas that's a good point, I'll give it a try having 2 infrastructure folders in the structure. Thanks for your feedback!
@@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.
Man, that's perfect, that's how i did it as well without even seeing your project.
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!
thanks for sharing. Very helpful and a good starting point
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?
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.
@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?
Domain is split by domain concerns. It is usually a centralized project that is shared as a nuget package
Wow, that's awesome approach..
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.
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.
@@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.
@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).
@@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.
@@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.
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?
Just set as return type something else , a Collection or a List. DbSet implements all these:
IQueryable, IEnumerable, IEnumerable, IQueryable, IAsyncEnumerable, IInfrastructure, IListSource
@@drm1983 Thats not a solution at all :)
I think he meant you can swap the db INSIDE ef. Not with ef. Ef can handle cosmos db as well.
Thanks for sharing your knowledge.
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?
Great explanation. Keep up the good work.
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.
Very well explained, Thank you !
Hi Nick. Thanks for the video! However, I am wondering why IApplicationDbContext interface contains DbSet properties, as they are part of infrastructure (entity framework)
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
@@nickchapsas Thanks!
@@nickchapsas would a better example be to have a repository interface in the Application project and the the implementation in the Infrastructure project?
when do you choose to use something like Mediatr or Brighter? what uses cases would use it and when would you not?
this is so perfect, thank you ♥
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?
DTOs, etc..
Hey @nickchapsas I like this structure but can we use this in each Microservice?
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 😁✌️.
Great work your videos are really helpful
Is their an example of cleanarchitecture with a seperate api project for contracts? To understand it better.
This is what I needed badly
How do you create migrations, i mean that I'm getting error about wrong project target and nothing helps
How can microservices implemented on that? Different solution for different services or different application layer project?
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?
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
Can this design be described as follows:
Domain: The what
Application: The How
Infrastructure: Server-side when
Presentation: Client-Side when
This is pure gold !
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
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.
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?
Loving these topics ! can you do authentication and authorization next? Or pagination too would be really helpful
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?
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)
is this only for single page applications because jason taylor clean code architecture is mentioned for single page application on their github repository
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?
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.
@@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?
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).
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?
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 ?
Hi Nick, great video. What is your view on vertical slicing architecture?
Hi Nick, thank you for this video
can you make a video about Blazor also?
07:44 - в application только интерфейс, а реализация в infruscructure, чтобы потом можно было легко подменять реализацию не меняя application
09:19 - единственная причина почему Presentation зависит от infruscructure - чтобы регистрировать сервисы
Hello nick can you tell me how to scaffold an entity from the domain layer in the presentation layer but at the same time i cant add a reference of domain layer in the presentation layer due to n tier architecture design?
I'm wondering, what does the word 'common' mean? I see it with purchased software dll's, this video and some other projects.
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.
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?
Thanks for the video.
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.
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.
Lets say that I have a solution, for WebUI, prepared in that way. Now I want to create API that will be used by some external service - for example mobile app. How should I make it? Could I create a new project here - next WebUI, and it'll drive from Domain, App and Infrstructrue? What if I will want to prepare API nuget client that helps using API in external services? If I will do it in simmilar way it became huge and some implementation will be included but never used ;/
Could you please help me with that?
Great videos, keep it up!!!
Is there a GitHub link for this sample project?
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)
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.
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?
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.
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 😋
I just stuff all in solution folder and it works!
Could you please show in the video how you actualy create this structure in Rider?
Is the domain project always called "Domain' or does it sometimes go by other names?
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.).
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.
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
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)
Why interfaces are in the Application layer? They should be inside Domain layer, shouldn't?
On the issue of registering services in a function in the Infrastructure layer, but otherwise keeping everything in the Infrastructure internal: whenever I try that, the dependency injection breaks because it can't instantiate any of the classes that are internal to a separate project (ie: in the Infrastructure, not in the Presentation). How do you get around this?
As long as the implementations are internal but the DI method it public and you don’t expose any of them outside as a parameter, it should work fine.
Is it a common practise to use microservies architecture with this 'clean architecture' approach for each microservice?
This is how I am working yes
thank you nick for this video. what do you think about abp framework as a starting template for clean architecture and DDD.
Awesome stuff
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.
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...
Thanks for the disclaimer, these kind of contradictions made me give up on learning clean architecture.
Sir. How do I structure a Project in C# the right way?
I'm pretty much on the same ground as @InvictuZ. Everyone says different things about the same topics. Can you guys provide examples? Thanks!
@@belvss896look at a course by Vladimir khorikov refactoring away from an anemic domain model towards a rich one. Khorikov has tons of examples