ecotoneframework / ecotone-dev

Ecotone Framework Development - This is Monorepo which contains all official public modules
https://docs.ecotone.tech
Other
37 stars 16 forks source link

Ecotone is attempting to instantiate handlers before proxies are generated #33

Closed aidan-casey closed 1 year ago

aidan-casey commented 2 years ago

Ecotone version(s) affected: *

Description Specifically within a Laravel application, lines 97-103 of EcotoneProvider "prepare" MessagingSystemConfiguration by looking for annotated classes and it would appear attempts to instantiate them. If using a cache, this builds up a cache for later.

After this step, lines 118-130, register "gateways" with the Laravel container. This basically builds proxies for those interfaces, including CommandBus and QueryBus.

The problem lies in if a handler has a dependency on one of these proxies. For example, I believe it is an okay practice to query some information using the QueryBus in a command handler.

How to reproduce

Reference QueryBus in the construct of a command handler:

class MyCommandHandler
{
    public function __construct(private readonly QueryBus)
    {}

    #[CommandHandler(MyCommand::class)]
    public function handle(MyCommand $command): void
    {
        $nextShortCode = $this->queryBus->send(new NextShortCodeQuery);

        // ...etc
    }
}

Possible Solution

Figure out a way to build and register these proxies earlier on. Or get rid of these proxy classes in favor for actual implementations.

dgafka commented 2 years ago

Hey @aidan-casey, Ye I agree, this how Symfony integration works actually. This definitely should be working the way you describe :)

For now you can try this solution, I believe it will works:

#[CommandHandler(MyCommand::class)]
public function handle(MyCommand $command, QueryBus $queryBus): void
{
    $nextShortCode = $this->queryBus->send(new NextShortCodeQuery);

    // ...etc
}
aidan-casey commented 2 years ago

Makes sense, @dgafka. What do you envision is the best way to solve this one? Building the proxy files earlier or shipping an implementation?

dgafka commented 2 years ago

I would say the former. Symfony integration actually do it with lazy proxy, in order to avoid fetching gateways to early. We could do the same for Laravel, by generating lazy proxy, that will call gateways afterwards (QueryBus).

Just for general understanding: CommandBus, QueryBus are Gateways.

Are you up for a challenge to take care of the implementation? :)

aidan-casey commented 2 years ago

Makes sense. Seems like it's important to remain with the proxy generator given the fact that custom Gateways can be created, correct?

Yeah, I can look into this further.

dgafka commented 2 years ago

Hmm not sure how would you achieve it without the proxy. If you build the gateway without the proxy, you will get instance of Ecotone\Messaging\Handler\Gateway\Gateway, so it needs to be wrapped in order to imitate interface. :)

As long as we can inject gateway within constructor and method (which just resolves service from DI by class name), then I am happy with that :+1: If you open PR with the idea you have, it will be easier for me to follow :)

dgafka commented 2 years ago

@aidan-casey can you recheck if this problem is fixed with newest Ecotone version?

dgafka commented 1 year ago

I believe this should be now fixed. Feel free to reopen if that's not the case :)

dgafka commented 1 year ago

I believe this should be now fixed. Feel free to reopen if that's not the case :)