-
-
Notifications
You must be signed in to change notification settings - Fork 239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Decorating command handlers #179
Comments
This is an old post but reading it made me realize I was not filtering out my decorators at registration time, which I think is a good idea. Bellow, I outlined what worked for me. public interface ICommandHandler<in TCommand, TResponse> where TCommand : ICommand where TResponse: class
{
Task<Result<TResponse>> Handle(TCommand command);
} // Decorators
public class CommandExceptionHandlingBehavior<TCommand, TResult> : ICommandHandler<TCommand, TResult> where TCommand : ICommand where TResult : class
{
private ICommandHandler<TCommand, TResult> NextCommandHandler { get; }
public CommandExceptionHandlingBehavior(ICommandHandler<TCommand, TResult> nextCommandHandler)
{
NextCommandHandler = nextCommandHandler;
}
public async Task<Result<TResult>> Handle(TCommand command)
{
try
{
return await NextCommandHandler.Handle(command);
}
catch (QuotaExceededException ex)
{
return Result<TResult>.Failure(ex.AsError());
}
catch (Exception ex)
{
return Result<TResult>.Failure(new Error
{
Message = ex.Message,
Reference = NextCommandHandler.GetType().ToString(),
Type = Error.ErrorTypes.UnknownError
});
}
}
}
public class CommandValidationBehavior<TCommand, TResult> : ICommandHandler<TCommand, TResult> where TCommand : ICommand where TResult : class
{
private ICommandHandler<TCommand, TResult> NextCommandHandler { get; }
private IValidator<TCommand> Validator { get; }
public CommandValidationBehavior(ICommandHandler<TCommand, TResult> nextCommandHandler, IValidator<TCommand> validator)
{
NextCommandHandler = nextCommandHandler;
Validator = validator;
}
public async Task<Result<TResult>> Handle(TCommand command)
{
var errors = await Validator.ValidateAsync(command);
if (errors.Any())
{
return Result<TResult>.Failure(errors);
}
return await NextCommandHandler.Handle(command);
}
} // IoC Configurations
services.Scan(scan => scan.FromCallingAssembly()
// First gather all the possible implementations of my commands and then filter out the decorators
.AddClasses(classes => classes.AssignableTo(typeof(ICommandHandler<,>)).Where(c => !c.IsAssignableTo(typeof(ICommandBehavior))))
.AsImplementedInterfaces()
.WithTransientLifetime()
);
services.Decorate(typeof(ICommandHandler<,>), typeof(CommandValidationBehavior<,>));
services.Decorate(typeof(ICommandHandler<,>), typeof(CommandExceptionHandlingBehavior<,>)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi dear,
I want to decorate command handlers with decorator Pattern in an ASP.NET Core app. So I registered command handers first and then register decorators.
But it doesn't work. I am using built-in IoC in ASP.NET Core and Scrutor.
You can see them below.
Registration of command handlers and decorators
Could you tell me how can I do that , please?
Thanks in advance
The text was updated successfully, but these errors were encountered: