@tiagohenrique7685

Hi Amichai! Greetings from Brazil!
I am so grateful for your series! I've been following this far and everything just gets better!! Congratulations! Content like this is very rare!

@liordagan5098

What?! Zero comments about the most beautiful part of this video?! 😍🐶 28:15

@ugochukwuumerie6378

Great content 👌 especially the ending part - Yes!. The pipeline behaviours are like class decorators which obeys the "O" in the SOLID principles - the class should be closed for modifications and open for extensions.

@patrykk.4630

Thanks for this video. I was waiting for a good explanation of MediatR behaviors and validating. Can't wait for domain and application validaiton breakthrough :D

@davidpccode

Hello great content. Thank you very much. I have read and seen a lot of content about command validation but I still can't find a reason that justifies so much over-engineering and so much complexity.  
I can achieve the same thing by injecting a class that performs all the validations with less than half the effort and with the same result.  what am i missing? Thanks in advance 👍

@gungoromer

Teşekkürler.

@tombalabomba3084

Great video, but where is the promised video where you talk about application and domain layer validation? I really need this! <3

@pilotboba

So let's go back to when I asked you why your Commands/Queries weren't your API contracts. You stated that you wanted to be able to change the commands/queries implementations without changing the contracts. Ok, fair enough.

However, now, you are validating the Command and not the request. So, when you return a validation problem it is possible you are defining a validation problem on a property that doesn't actually exist on the contract. 

So, your RegisterRequest could have FullName which you map to First Name, Last Name in your command. Your validator finds the Last Name is empty and returns a problem that states, LastName is required or some such error. How is the client supposed to fix this, because he has no LastName property in his contract?

Am, I seeing this correctly, or did I miss something?

@Jeroen3001

Instead of invoking a Dynamic Call Site by using the 'dynamic' keyword in '(dynamic)errors'  (which is slow) the same effect is accomplished by a simple cast from an object reference:

'(TResponse)(object)errors'

I try to prevent to use the keyword 'dynamic' at all times when possible.

@ariefmuhammadlubis1803

Finally, I'm very happy and great video

@being_aslam_tiger

Thanks for creating awesome stuff. Please keep making videos on c#.

@baulron

Thanks!

@KarwanEssmat

Well Done Amichai, 
I am excited to fo find your course. it is truly helpful.
Actually, I did not use your Error0r library so I had some challenges in returning the exception errors and I used my approach.
Thanks for sharing.

@fakeITDevTeam

i wish i could be as good as you guys in software development world.

@StandleyPeter

I really enjoy the series. Have learned a lot from these series. Anyway, alt+z should toggle the words wrap automatically.

@sunnypatel1045

Hey dude love your content. Are you going to do a video on testing the api? Love to see your strategy etc.

@novalogic1265

Great video as usual. Just one thing, instead dynamic I've implemented in this way: First, I split  Command and Query into 2 interfaces
public interface ICommand<TResponse> : IRequest<ErrorOr<TResponse>>
    {
    }


public class ValidationBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, ErrorOr<TResponse>>
        where TRequest : ICommand<TResponse>
    {
        private readonly IEnumerable<IValidator<TRequest>> _validators;
        public ValidationBehaviour(IEnumerable<IValidator<TRequest>> validators)
        {
            _validators = validators;
        }
        public async Task<ErrorOr<TResponse>> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<ErrorOr<TResponse>> next)
        {
            if (!_validators.Any())
            {
                return await next();
            }

            var context = new ValidationContext<TRequest>(request);
            var validationResults = await Task.WhenAll(_validators.Select(v => v.ValidateAsync(context, cancellationToken)));
            var errors = validationResults.SelectMany(result => result.ToErrors()).ToList();

            if (!errors.Any())
            {
                return await next();
            }
            return errors;
        }
        }

Because, if I need ErrorOr in e.g. some behavior (logging or whatever) after next() to log something with this approach I have an ErrorOr object. What do you think?
Also, I dont like dynamic and I dont like exceptions 😉
Edit: result.ToErrors() line ToErrors is an extension😀

@ugursesen7629

the tutorials are really great, thanks a lot

@mahditalebi1770

Thanks for the video. It's a little bit hard to read without word wrapping and big font. 
if you could maybe close the files list or decrease font a little I think it would be much easier to undrestand.

@alexc.5781

All my sympathies to your enter key