Thank you. I was rolling out my own Clean Architecture solution with MediatR, Serilog, CQRS etc... but with your template, it will get me up and running much faster for those side projects :) Thank you again. It looks brilliant!
Thanks you for this helpful video. We've been using Clean Architecture in our Multi-Tenant/SaaS boilerplate template since the beginning and it's proven to be a great choice.
Hey Ardalis ! Thank you so much for this newer version. You are the goat. One question, what about if you are dealing with some reports and it’s more efficient just to have a plain Sql command ? Or you don’t want to use EF at all ? Or instead of fetching a single entity from EF fetch I want to fetch a custom entity in an api get call ? What’s your solution in those kind of cases. Thanks !
The Query services defined in Infrastructure and used in some of the Read UseCases is the approach I recommend (and that's why it's in the template even though the case there doesn't really justify having it).
@@Ardalis This was what i was talking about ! Such a great and elegant way to solve this. I love Clean Architecture, but I have mixed feelings about the database being so underutilized. So, I want to achieve and follow some Clean Architecture principles while at the same time empowering my database. Thanks for your response
Great content, as usual! Would you please explain the difference between an endpoint validator and a usecase validator? And why do you recommend using different classes for requests (api) and commands/queries (usecase)? Thanks!
The only difference is really the layer where it happens and the code that makes it happen. Using MediatR behaviors (or similar) in your UseCases layer allows you to "own" the code that does this work as well as all of the Queries, Commands, etc. involved. If you change the UI (from controllers to minimal apis to fast endpoints to uber-special endpoints to gRPC to who-knows-what-next) you don't need to touch the UseCases, and they will continue to work and validate their DTOs independently. That's the case for doing it there. Of course, Fast Endpoints includes great support for validation out of the box, and in practice the DTOs used for Requests and Responses are likely to be very closely aligned with your Queries, Commands, and result DTOs from your UseCases. So, maybe it makes sense and is less code to just do (more of) the work in the Endpoints and the UI layer. The tradeoff is more coupling to Fast Endpoints but less code needed. I show both in order to let folks make their own decision, and because it is much easier to remove code (you decide you don't need) than to create code from scratch (if you need it).
In recent couple of years, I've doing Java. Now I'm back to . NET again. I've just finished your great DDD course and now this awesome project template. I'm so thrilled to start my next project with this template. By the way, I like your new haircut ;)
The Aspire shop is moving really quickly, so I'll probably hold off until it stabilizes later this year. I'm trying to keep up with their stuff, myself! :)
Hello, your template is awesome, I am always checking it and comparing it to others, I sure love the REPR pattern, the only headache I have is how to integrate authentication and authorization while respecting the intent of the architecture. A tutorial would be awesome
@@Ardalis I manage to make it work for my project using jwt auth/auth with fastendpoints and swagger, if you like I can send you the repo link, maybe it will help
Thank you for this helpful video. I have a couple of questions: - How can I differentiate between various create/update/delete C# files? For instance, if I have multiple Create files opened, it may become confusing. Would renaming the files while keeping the class names be a good solution? - How does one correlate a transaction using a correlation ID, and how would this integrate with the given template? Keep up the great work!
I use the folder/namespace to differentiate and avoid duplicating resource names in the fully qualified class names if possible. Yes that means you could have two “Create.cs” file tabs open but in practice it should be rare you need two such files open to complete one feature. Do one, commit it, close the files, do the next. For correlations i typically put a property on a base request message of type guid that initializes to NewGuid() and then pass that through to use cases etc.
Sure. Just to put you completely in control, what's your entity? Also, I already have a more full-featured sample in the /sample folder of the Clean Architecture github repo, which shows a couple of aggregates (Projects, which have ToDoItems and Contributors). Have you seen that?
@@Ardalis yes I saw and I have some success but I'm sure there a lot of cool things I don't know yet. About entries I mean database entities with relations
I’m a fan of (and coined the term) the REPR pattern or Request-Endpoint-Response. Makes it much easier to manage your endpoints and their related messages in larger projects.
Well it's mostly useful for apps that benefit from a DDD approach and get value from both testing and long-term maintainability. If your needs are simple, then just stick to a single project until you start feeling pain from the lack of logical separation that affords.
If you invest some time in understanding DDD and adopt sound clean architecture principals you will reap the benefits. I took felt everything was over engineered and struggled to understand where things went etc. but with experience it all comes together. 👍
Design by contract allows for loosely coupled entities. This allows large teams to work together in different branches and all merge successfully for deployment.
Thank you. I was rolling out my own Clean Architecture solution with MediatR, Serilog, CQRS etc... but with your template, it will get me up and running much faster for those side projects :) Thank you again. It looks brilliant!
Glad it helped!
Thanks you for this helpful video. We've been using Clean Architecture in our Multi-Tenant/SaaS boilerplate template since the beginning and it's proven to be a great choice.
Glad it was helpful!
Great template will definitely be using it as well.
Glad you like it!
Hey Ardalis ! Thank you so much for this newer version. You are the goat. One question, what about if you are dealing with some reports and it’s more efficient just to have a plain Sql command ? Or you don’t want to use EF at all ? Or instead of fetching a single entity from EF fetch I want to fetch a custom entity in an api get call ? What’s your solution in those kind of cases. Thanks !
The Query services defined in Infrastructure and used in some of the Read UseCases is the approach I recommend (and that's why it's in the template even though the case there doesn't really justify having it).
@@Ardalis This was what i was talking about ! Such a great and elegant way to solve this. I love Clean Architecture, but I have mixed feelings about the database being so underutilized. So, I want to achieve and follow some Clean Architecture principles while at the same time empowering my database. Thanks for your response
Great content, as usual!
Would you please explain the difference between an endpoint validator and a usecase validator? And why do you recommend using different classes for requests (api) and commands/queries (usecase)? Thanks!
The only difference is really the layer where it happens and the code that makes it happen.
Using MediatR behaviors (or similar) in your UseCases layer allows you to "own" the code that does this work as well as all of the Queries, Commands, etc. involved. If you change the UI (from controllers to minimal apis to fast endpoints to uber-special endpoints to gRPC to who-knows-what-next) you don't need to touch the UseCases, and they will continue to work and validate their DTOs independently. That's the case for doing it there.
Of course, Fast Endpoints includes great support for validation out of the box, and in practice the DTOs used for Requests and Responses are likely to be very closely aligned with your Queries, Commands, and result DTOs from your UseCases. So, maybe it makes sense and is less code to just do (more of) the work in the Endpoints and the UI layer. The tradeoff is more coupling to Fast Endpoints but less code needed.
I show both in order to let folks make their own decision, and because it is much easier to remove code (you decide you don't need) than to create code from scratch (if you need it).
In recent couple of years, I've doing Java. Now I'm back to . NET again. I've just finished your great DDD course and now this awesome project template. I'm so thrilled to start my next project with this template. By the way, I like your new haircut ;)
Thanks!
Keep up all the good work Steve, love this video.
need one for new eshop project as well. ( new one)
The Aspire shop is moving really quickly, so I'll probably hold off until it stabilizes later this year. I'm trying to keep up with their stuff, myself! :)
Hello, your template is awesome, I am always checking it and comparing it to others, I sure love the REPR pattern, the only headache I have is how to integrate authentication and authorization while respecting the intent of the architecture. A tutorial would be awesome
Yeah, I need to add that at some point.
A more full-fledged sample that includes auth is eShopOnWeb, available here:
github.com/nimblepros/eshoponweb
@@Ardalis I manage to make it work for my project using jwt auth/auth with fastendpoints and swagger, if you like I can send you the repo link, maybe it will help
Thank you for this helpful video. I have a couple of questions:
- How can I differentiate between various create/update/delete C# files? For instance, if I have multiple Create files opened, it may become confusing. Would renaming the files while keeping the class names be a good solution?
- How does one correlate a transaction using a correlation ID, and how would this integrate with the given template?
Keep up the great work!
I use the folder/namespace to differentiate and avoid duplicating resource names in the fully qualified class names if possible. Yes that means you could have two “Create.cs” file tabs open but in practice it should be rare you need two such files open to complete one feature. Do one, commit it, close the files, do the next.
For correlations i typically put a property on a base request message of type guid that initializes to NewGuid() and then pass that through to use cases etc.
Great Stuff!!! Thanks...
Glad you enjoyed it!
I wanna see a full tutorial how to add a new CRUD element. From Entity model to swagger docs description for items
Sure. Just to put you completely in control, what's your entity? Also, I already have a more full-featured sample in the /sample folder of the Clean Architecture github repo, which shows a couple of aggregates (Projects, which have ToDoItems and Contributors). Have you seen that?
@@Ardalis yes I saw and I have some success but I'm sure there a lot of cool things I don't know yet.
About entries I mean database entities with relations
Why do you prefer fastendpoints over minimal api definitions?
I’m a fan of (and coined the term) the REPR pattern or Request-Endpoint-Response. Makes it much easier to manage your endpoints and their related messages in larger projects.
Hi Steve, can i ask why you don't run papercut as a windows service instead of in a Docker container?
Never tried. The docker container approach is so simple and I have several utilities I run that way (RabbitMQ, Seq, etc.).
In delete contributor handler, does mediator handles any failures occur in SendEmailAsync method
Currently any exception just causes the overall request to fail. You could certainly add try/cetch/retry and/or Result support if desired.
Do you have a enterprise example.
eShopOnWeb is probably the best thing to check out: github.com/NimblePros/eShopOnWeb
Thank you GOAT
❤️
Great, but clean architecture is so verbose and complex :)
Well it's mostly useful for apps that benefit from a DDD approach and get value from both testing and long-term maintainability. If your needs are simple, then just stick to a single project until you start feeling pain from the lack of logical separation that affords.
If you invest some time in understanding DDD and adopt sound clean architecture principals you will reap the benefits. I took felt everything was over engineered and struggled to understand where things went etc. but with experience it all comes together. 👍
Design by contract allows for loosely coupled entities. This allows large teams to work together in different branches and all merge successfully for deployment.