question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Optional Decorators?

See original GitHub issue

Hello!

I have the following setup. This code is very similiar to my earlier question: https://github.com/khellang/Scrutor/issues/68

            services.Scan(s =>
            {
                s.FromAssembliesOf(typeof(ApplicationLayerServiceProviderExtensions))
                    .AddClasses(p => p.AssignableTo(typeof(ICommandHandler<>)).Where(x => !x.IsGenericType))
                    .AsClosedTypeOf(typeof(ICommandHandler<>))
                    .WithTransientLifetime();

                s.FromAssembliesOf(typeof(ApplicationLayerServiceProviderExtensions))
                    .AddClasses(p => p.AssignableTo(typeof(AbstractValidator<>)).Where(x => !x.IsGenericType))
                    .AsClosedTypeOf(typeof(IValidator<>))
                    .WithTransientLifetime();
            });

            services.Decorate(typeof(ICommandHandler<>), typeof(ValidationCommandHandlerDecorator<>));
            services.Decorate(typeof(ICommandHandler<>), typeof(LoggingCommandHandlerDecorator<>));

The AsClosedTypeOf() code is this:

        public static ILifetimeSelector AsClosedTypeOf(this IServiceTypeSelector selector, Type closedType)
        {
            return selector.As(t => t
                .GetInterfaces()
                .Where(p => p.IsGenericType && p.GetGenericTypeDefinition() == closedType)
            );
        }

my ValidationCommandHandlerDecorator<> looks like this:

    public class ValidationCommandHandlerDecorator<TCommand>
        : ICommandHandler<TCommand> where TCommand : ICommand
    {
        private readonly ICommandHandler<TCommand> _innerHandler;
        private readonly IValidator<TCommand> _validator;

        public ValidationCommandHandlerDecorator(
            ICommandHandler<TCommand> innerHandler,
            IValidator<TCommand> validator)
        {
            _innerHandler = innerHandler;
            _validator = validator;
        }

        public Task HandleAsync(TCommand command)
        {
            var validationResult = _validator.Validate(command);

            // Other code is omitted

            return _innerHandler.HandleAsync(command);
        }
    }

Right now, I need to create an implementation of IValidator<> for every command that gets executed. If it does not exist, an exception is thrown because the implementation can’t be found.

I would like to support that Ivalidator<> is optional. Sometimes I have a command that I need no validator for. Right now I HAVE to create an implementation of IValidator<> that is just an empty class to satisfy this code.

Could you help me out?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
sander1095commented, Dec 9, 2020

I am now using your last suggestion (IValidator<TCommand> validator = null) and that works! thanks!

0reactions
sander1095commented, Dec 3, 2020

Thank you very much, I will try this out!

Read more comments on GitHub >

github_iconTop Results From Across the Web

python - How to build a decorator with optional parameters?
If it is passed arguments, then it is first called with them and then the result of that preliminary call (which must itself...
Read more >
How To Write A Decorator With An Optional Argument?
When playing with decorators (this week's challenge) I got stuck: how do you write a decorator that takes an optional argument?
Read more >
@Self or @Optional @Host? The visual guide to Angular ...
@Host() decorator makes Angular to look for the injector on the component itself, so in that regard it may look similar to the...
Read more >
Self, @SkipSelf & @Optional Decorators Angular
Self, @SkipSelf, @Optional are Angular Decorators configure how the DI resolve the dependencies. They modify the behavior of injectors.
Read more >
Fully-typed Python decorator with optional arguments
This is my very first blog post! In this short post, I will show the blueprint for a fully-typed Python decorator that optionally...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found