Amichai Mantinband

Amichai Mantinband

Hey there! In this channel I'm creating industry-level tutorials about coding, design patterns, architecture, and the latest and greatest libraries, tricks, and tips you should definitely know about.

Winglang in 10 minutes

Winglang in 10 minutes

.NET in 300 seconds

.NET in 300 seconds

DDD's Holy Grail

DDD's Holy Grail

Пікірлер

  • @jodainemoore8300
    @jodainemoore8300Күн бұрын

    Great Videos, Please can you do one on Composition and Or with Strategy Pattern, I have been struggling with these for months.

  • @floriandraxler3868
    @floriandraxler3868Күн бұрын

    is that video speed up a little or do you have some sort of voice adjustment going on?

  • @yufgyug3735
    @yufgyug3735Күн бұрын

    Ive been using this approach for a long time now. What i like about it, is that it forces you to deal with some code smells 1. exceptions are for exceptional situations - for example, a method parameter should under no circumstance be a null, but somehow is - the program cannot continue handling the request 2. explicitly deal with specific error situations - how do we handle situation X? how do we handle situation Y?

  • @Tony-dp1rl
    @Tony-dp1rl2 күн бұрын

    Using exceptions for logic branches that you KNOW how to handle without exceptions, such as by returning a suitable response, is not a good idea. It creates a different user experience in most cases, and it creates far more overhead in terms of error logging, monitoring, unit testing, etc. Nothing worse than a unit test, or functional/integration test, that has to say "did this throw an exception?" .. "yes, test passed" ... just stupid :)

  • @amantinband
    @amantinband2 күн бұрын

    I generally agree and have videos on the channel relaying this exact point. The truth is in the middle. Both approaches have great benefits and drawbacks. I’m demonstrating what I would personally use for a small-medium, mostly CRUD app when looking to get things up and running as fast as possible.

  • @dougbas3980
    @dougbas39803 күн бұрын

    Very powerful tool. Yoou have convinced me this is a tool I need. THANK YOU.

  • @patfre
    @patfre3 күн бұрын

    Exception should only ever be used IF AND ONLY IF ITS THE ONLY OPTION. Exceptions are incredibly memory and processing intensive and should be reduced as much as possible so even suggesting to use it just because it’s simpler is one heck of a quick way to make people fail an interview

  • @amantinband
    @amantinband2 күн бұрын

    Sounds like you’ll enjoy this video: Exceptions are evil. This is what I do instead. kzread.info/dash/bejne/ZJydrdt_mZTTl6w.html

  • @relax4o
    @relax4o3 күн бұрын

    Hi Amichai, I think you missed another solution which is also used by Vaughn Vernon. Have you considered creating a separate value object that holds the reference ids? For example "record HostMenu(HostId hostId, MenuId menuId);" which then can be easily used in OwnsMany() and you can again define each with HasConversion(). I think this approach is easier to understand and depending on UL, it can bring better clarity. For example, in IDDD book VV is using a value object CommittedBacklogItem within the Sprint aggregate and that value object is used in a HashSet inside the Sprint object. I really like that approach because it also brings a good understanding of what that actually mean for the sprint. It's not just a list of backlog items but they are actually backlog items committed for the sprint. Same goes for ScheduledBacklogItem within the Release aggregate. Also, in version 8 the EF Core team introduced a ComplexProperty which is really good for such cases, though, it's still very limited and they cannot yet properly be used for collections or keys but once they improve them it will be really cool feature to use.

  • @IoannisHorgos-bv1in
    @IoannisHorgos-bv1in3 күн бұрын

    Great video! Thank you for your effort! What software do you use for creating these boxes and arrows as you drag your mouse?

  • @amantinband
    @amantinband2 күн бұрын

    Presentify

  • @ErikVasilyan183
    @ErikVasilyan1833 күн бұрын

    Talking about DDD, what you think about to never have conditionals in application services? I see you do "productRepository.Exists()" and checking if product exists, if it exists you create the review if not you throw. To not have logic like that in app service you could do that your product domain model creates the review, like "product.CreateReview()". So in app service you get the actual product doing "productRepository.getProduct(ProductId)" and you get the product or else throw, then you create the review using that product.

  • @amantinband
    @amantinband2 күн бұрын

    What’s the motivation for not having conditionals in application services?

  • @saiuan4562
    @saiuan45623 күн бұрын

    Why not just return either the record, or 200 OK with empty list/no record, if it was not found? Is that not okay?

  • @amantinband
    @amantinband2 күн бұрын

    Both approaches are good and valid. Personally, if I get to choose, I return 404 for *parent* resource not found, and 200 ok and empty list for collection not found/empty

  • @SodalisUK
    @SodalisUK5 күн бұрын

    Does the same principle apply to other languages (python, php for example) that have exceptions and can you have an equivalent to ErrorOr in those languages?

  • @iantabron
    @iantabron5 күн бұрын

    I generally disagree with throwing exceptions in non-exceptional circumstances. However, in this example I more strongly disagree with throwing an exception in a service layer that contains an HTTP response code. You are assuming you will always use your service layer with a web-based API, and tying it to this usage. A service layer should be just that - services. An API layer, such as WebAPI in this case, should have the responsibility of returning the appropriate HTTP response code.

  • @amantinband
    @amantinband5 күн бұрын

    Please note that we’re talking about simple, small to medium applications that are mostly CRUD. I share your opinion for larger, more complex applications. For the smaller apps, personally, I’d choose the higher coupling, higher cohesion approach and refactor if needed

  • @georgebelletty7861
    @georgebelletty78615 күн бұрын

    I do like ErrorOr I use it in all our projects

  • @WasifKizilbash
    @WasifKizilbash5 күн бұрын

    The best, concise, to-the-point, relevant and CLEAR communication!! above all, I really like the way you kept on showing the Diagram and linked it with the Code, that is where we are! I've never seen any .NET video instructors making such a clear and crisp connection to the Infographic vs Code!! great stuff! will definitely cover your entire course!! This is coming from a full stack .NET developer who has been dirtying hands for the last 15 years!! bravo! more power to you mate! love from Australia!

  • @maxweinbrown1180
    @maxweinbrown11805 күн бұрын

    "Repositories go into either the application or domain layers" I believe their implementation goes into the infrastructure layer, but their definition (if you're working with interfaces/headers/protocols) belongs to the domain layer. This keeps the domain from being dependent on the infra layer, while still making use of it, often through dependency injection

  • @petherpettersson6152
    @petherpettersson61526 күн бұрын

    What I can't really buy on the cons of Exceptions is the cost of them, sure, it has some resource cost, but who designs a product to do the bad incorrect stuff all the time? There's supposed to be validation on input on the frontend, the one on backend is just a safeguard, so will have no Exceptions there if the frontend has done it's job, so then the only exceptions coming are the ones where something goes bad during processing?

  • @amantinband
    @amantinband6 күн бұрын

    When using exceptions for flow control, by definition you’re using exceptions for flows that are not exceptional. Depending on the scale and requirements of the app, this can be significant

  • @LarryGroot
    @LarryGroot6 күн бұрын

    Thank you very much. Maybe Next Video how you would log and which framework you would use.

  • @amantinband
    @amantinband6 күн бұрын

    It’s coming

  • @kennethcanet1633
    @kennethcanet16336 күн бұрын

    discount code invalid.

  • @robertmills8101
    @robertmills81016 күн бұрын

    Why are you separating command and query outside of IAuthenticationService? No code outside of the implementation cares. You're introducing something and a LOT of code that doesn't matter. The implementation of authentication's repository (maybe IAuthenticationRepository) might care because there is a read side and a write/transaction side, but not at the front end or what should be a very thin, single line, of code in the controller. Oh, and what happens if login requires a counter update to restrict failures every n minutes? Also, even query commands will/might update the log database, but I guess that doesn't count. Sorry for the rant.

  • @ameyashinde423
    @ameyashinde4236 күн бұрын

    Learnt something new. Thanks so much

  • @pilotboba
    @pilotboba7 күн бұрын

    One thing I disagree with is ever returning a 404 on a List (collection) endpoint. I'm not sure why your List asked for a product Id. But a list should return an empty collection if no resources match the predicate.

  • @amantinband
    @amantinband7 күн бұрын

    If it's up to me, I choose 404 for parent resource not found, but both are fine and valid approaches

  • @pilotboba
    @pilotboba7 күн бұрын

    @@amantinband Oh so you are listing some child resources of a product. I guess I could see returning a 404 in the case of the missing product.

  • @jimread2354
    @jimread23547 күн бұрын

    That's funny, I completely and fundamentally disagree. IMO, if you have a simple application, you can use return codes, but complex applications with lots of shared code and deep stacks of function calls benefit enormously from Exceptions. Exceptions simplify error handling and code readability MASSIVELY over returning error codes. Exceptions were a response to return codes' lack of scalability because return codes require that EVERY time a function is called, whatever calls it has to have logic to handle the error condition right there. Exceptions allow you to simply pass the error up the chain until something that cares or knows what to do will actually handle it. Further, exception handling is done outside the general flow of logic so someone reading the code can actually understand what is 'supposed' to be happening and there's no chance that anything UP the stack is going to continue executing in a faulty state. On top of that, IMO, it's a TERRIBLE idea to have multiple outputs from a given function. It's bad enough to have the possibility of null or an object, but to then throw in the possibility of a third type to check and unpack the result of every function call? How is that scalable? It's a rat's nest of error handling! That's the beauty of an 'out' parameter is you can have the function return a specific type of result and then use the object if it's valid or else handle the case of it not being valid. The other great power of an Exception is that you can add context as the stack unwinds at the levels where it makes sense. Return codes can only change the context and you might lose vital information about what happened in the error situation. You're basically left with the choice of a user being told that there was a divide by zero error OR that the review didn't get added with no information about WHY. For instance, in a complex application a UI action will likely start a cascade of function calls splitting off into different directions to handle the different subtasks associated with with whatever the user just asked for. An exception deep in the bowels of that can say there was a divide by zero error, but then that can propagate to a failure to generate a star rating value which can then be caught closer to the UI level and told that the review couldn't be added. When you're building the message for the user and the message for the log, you'll have different info you can use to generate useful information in both contexts right at your fingertips without generating multiple log entries that you have to then piece together. IMO, you should throw Exceptions if the code you're in can't handle the current logical situation. For instance, adding a review to a product that doesn't exist. But if the code you're in CAN handle the situation, like perhaps you're adding an item to a list of items that share some property, but nothing has been added with that particular property yet, you should create the list for those items--no need for an exception or return code. Not using exceptions and relying on return codes is going backwards. And returning multiple data types from a function has always been a really bad idea from a readability and usability standpoint. The only real use case for return codes is in headless programs or highly performant libraries; but you better be sure the tradeoff in readability and debuggability is worth it.

  • @amantinband
    @amantinband7 күн бұрын

    Thanks for taking the time to share your thought and experience. My opinion around this topic is shaped from suffering bad implementations of exceptions for flow control in numerous large complex projects within Microsoft. I elaborate my opinion in more detail in this video: kzread.info/dash/bejne/ZJydrdt_mZTTl6w.html In any case, drawbacks and benefits to both approaches. They can both be implemented well and horrible. Plus, personal taste etc'.

  • @dimitryselin4225
    @dimitryselin42257 күн бұрын

    @@amantinband I want to add some text to this big comment. In big applications we ussualy work with diffrent nuget-packages, call low-level code of c/c++ dll from c#, send http-queries and so on. Often all this stuff generate exceptions (and some authors of libraries say that exception handling is the normal flow of using their packages). So in that case you need handle both: error codes and standard c# exceptions. These approaches lead to complicated error handling, lots of exception hadling code and of course bugs. And last but not least - your entire architecture will strong link with lib. (I hope you know that authors can change package license, stop maintenance and even do what happened to the package "moq") P.S. This is not about you Amantin))

  • @MahmoudSaed98
    @MahmoudSaed987 күн бұрын

    source code please

  • @amantinband
    @amantinband7 күн бұрын

    Hey Mahmoud, the source code is available for patrons and members. The description has all the relevant links

  • @krccmsitp2884
    @krccmsitp28847 күн бұрын

    3:37 I concur. In domain-centric, i.e. non-CRUD applications/modules, exceptions don't fit well.

  • @tchial0
    @tchial07 күн бұрын

    Simple and good analysis of what approach to choose.

  • @harrisonwell1719
    @harrisonwell17197 күн бұрын

    I found ErrorOr Adds a lot of unnecessary code

  • @amantinband
    @amantinband7 күн бұрын

    That's the main drawback of being explicit

  • @parlor3115
    @parlor31157 күн бұрын

    Not really, if you look closely, it's as much code as the exception approach. But I prefer this approach because it's more readable (the return type tells you everything about the method)

  • @petherpettersson6152
    @petherpettersson61526 күн бұрын

    @@parlor3115 Not really, since in every endpoint you will need to add code to handle if you should return the result, or the error if there is anything. Whilst a global exception handler is just that, global, so you do not have to do anything special for it to work. So requiring 5 to 10 extra rows of code is not as much code as no extra rows. *Edit* And then we have the extra try+catch code on top of that...

  • @parlor3115
    @parlor31156 күн бұрын

    @peth You only handle at the level you want to access the success data in and you have to handle either the exception (try catch) or the return. Otherwise, you'll just let the return propagate as is. And in case of generic and expected errors (validation, record not found, ...), then you'll return those at the last step (at the action method), where an after middleware is dispatched that will check the response and handle it accordingly just like a global error handler. With this, you'll be right the same amount of code while saving on performance.

  • @DavidSmith-ef4eh
    @DavidSmith-ef4eh7 күн бұрын

    How would you translate the error messages on apis with multi language support?

  • @krccmsitp2884
    @krccmsitp28847 күн бұрын

    How would you do that with exceptions?

  • @tchial0
    @tchial07 күн бұрын

    I would probably create a service class that returns a message according to the language. And have message templates.

  • @krccmsitp2884
    @krccmsitp28847 күн бұрын

    @@tchial0 there's no difference in this

  • @rankarat
    @rankarat7 күн бұрын

    Are you also responsible for the client-side development? If so, consider creating a shared project to house a mapping system and resource files. The API will return a code indicating a problem, which will act as a key in the resource file. This approach will facilitate easy management of multiple languages.

  • @tchial0
    @tchial07 күн бұрын

    @@krccmsitp2884 ​ Let's say (or code, lol): "var errorMessage = cultureService.GetErrorMessageById(errorMessageId, param1, ...)"

  • @user-zc1qr2ek5f
    @user-zc1qr2ek5f7 күн бұрын

    Why don't use Record for value objects?

  • @alexgoncharov6430
    @alexgoncharov64307 күн бұрын

    In my experience, when you don’t use global handlers and exceptions as your default error handling mechanism, the code becomes a lot more complex, you would just write a ton of meaningless code just to propagate the error up the call stack - exactly what exceptions do when you forget about error handling, and you get a nice stacktrace in that case so you can find the cause of your error easily. Once you do, you can add adjust the error handling. That’s much better than relying on programmers always doing a correct handling and adding all the context info after each function call. That’s not naive approach, that’s very practical approach

  • @NoTarantino
    @NoTarantino8 күн бұрын

    Hi I am trying to learn dotnet. Think you are a great at giving explanations. But it would have be great to have links to repos for each lesson. I get stressed out not knowing if it will build or not. It can be a bit unclear of were you are watch list etc. Your videos probably have different setting and different versions.

  • @NoTarantino
    @NoTarantino8 күн бұрын

    Ah the playlist was in reverted order😅

  • @AshrafSada
    @AshrafSada9 күн бұрын

    For windows users, dotnet sln .\solutionFileName.sln add (ls -r **/**/**.csproj)

  • @mstislavmaslennikov326
    @mstislavmaslennikov32611 күн бұрын

    Thank you for the nice review and demonstration!

  • @RealmOfCode
    @RealmOfCode11 күн бұрын

    You're going too fast... Sorry.

  • @rayawwad2921
    @rayawwad29212 күн бұрын

    It’s not that hard tho

  • @RealmOfCode
    @RealmOfCode2 күн бұрын

    @@rayawwad2921 Oh! you're one of those...

  • @xybersurfer
    @xybersurfer12 күн бұрын

    any tips on how to do global error handling in Blazor? ErrorBoundary doesn't seem to catch everything

  • @MartinoBordin
    @MartinoBordin12 күн бұрын

    Can we use it also for grpc services?

  • @ashoktandan2372
    @ashoktandan237212 күн бұрын

    why scoped for IDBConnectionFactory class?

  • @Buutyful
    @Buutyful12 күн бұрын

    perfect video 10/10

  • @pierre9368
    @pierre936812 күн бұрын

    Bad description of the problem. Task.WhenAll is a method that returns TASK, so use await same as for any task.

  • @afgone123456
    @afgone12345613 күн бұрын

    So if a client comes back with a traceid how would a developer find the real issue for that request? Are you saying we need to log it to db or something using the error endpoint?

  • @ashu3769
    @ashu376913 күн бұрын

    which tool you are using and how to set this up?

  • @harrisonwell1719
    @harrisonwell171913 күн бұрын

    why you don't respond to questions in the comments?

  • @AslamNazeerShaikh
    @AslamNazeerShaikh13 күн бұрын

    Not sure if this is 100% true or not ?! 🤔

  • @amantinband
    @amantinband13 күн бұрын

    I can’t always keep up with all the comments.. sorry if I missed your previous message 🙏🏼

  • @turcanuioangeorge4750
    @turcanuioangeorge475013 күн бұрын

    What is the tool you used to highlight code? Or is it just done in post production

  • @amantinband
    @amantinband13 күн бұрын

    Presentify

  • @felipecosta9889
    @felipecosta988913 күн бұрын

    Great content. One question. Is it best practice to throw exceptions in my code and catch them with global error handling? Or is it better to throw only exceptions that cannot be predicted?

  • @amantinband
    @amantinband13 күн бұрын

    This is exactly next Monday’s video

  • @SerafimMakris
    @SerafimMakris13 күн бұрын

    Good job. clean code as usual. i Hate you :D :D :D Ty @amantinband

  • @solvestation
    @solvestation13 күн бұрын

    Great tutorial. I would like to ask if the implementation is usable in a .net 8 MVC project? Thank you @Amichai

  • @amantinband
    @amantinband13 күн бұрын

    Yep

  • @solvestation
    @solvestation13 күн бұрын

    @@amantinband Thank you

  • @gopimech2030
    @gopimech203013 күн бұрын

    Nice video on global exceptions, but for Global Exceptions we inherit from IExceptionHandler which provides more flexibility by implementing multiple exception handlers from it. Do you say this approach is more flexible and recommended?

  • @amantinband
    @amantinband13 күн бұрын

    IExceptionHandler is more flexible. But comes with more boilerplate. If you need the flexibility, it's superior to an error handling endpoint

  • @obinnaokafor6252
    @obinnaokafor625213 күн бұрын

    What icon plugin are you using in your VS Code?

  • @amantinband
    @amantinband13 күн бұрын

    vscode-icons

  • @vuhoang5903
    @vuhoang590313 күн бұрын

    I have a question, when applying EF Core or other ORM in our .NET Clean Architecture project then the classes that we perform the mapping on is the entities in the Domain layer or what?

  • @10Totti
    @10Totti13 күн бұрын

    Great tutorial, but why not use a new IExceptionHandler abstraction for managing exceptions ?

  • @amantinband
    @amantinband13 күн бұрын

    I would choose IExceptionHandler over this approach for larger applications that need the modularity. For smaller apps, I personally prefer this approach

  • @Eirenarch
    @Eirenarch13 күн бұрын

    I don't understand the value of separate endpoint. Why not have a middleware that catches exceptions discriminates by their types, builds the appropriate ProblemDetails and writes it to the response

  • @amantinband
    @amantinband13 күн бұрын

    Both are solid choices. It mostly comes down to preference

  • @Dustyy01
    @Dustyy0113 күн бұрын

    There is no benefit in using the route approach like this. Normally you handle the exception using the IExceptionHandler interface and if you return false in the TryHandleError method, the route will receive the exception to further process (e.g. show a nice error html page). If you return true your exception is handled. I dont know any other reason why you want to use the route instead of the Interface in a plain API

  • @Fikusiklol
    @Fikusiklol6 күн бұрын

    @@Dustyy01 I agree aswell. If you want granular exception handling - IExceptionHandler is the way to go. However for easy/small services both approaches mentioned above are just fine.