Hi team, I have several modules that I add to Spry...
# help
w
Hi team, I have several modules that I add to Spryker. I would like to share code between them to follow DRY principle. I tried several approaches involving the different
DependencyProvider
(
AbstractBundleDependencyProvider
,
AbstractDependencyProvider
) and their methods such as
setGlobal
in one module or using
configure()
to set it to global like proposed here https://docs.spryker.com/docs/scos/dev/back-end-development/factory/inject-dependencies-within-factories-container-globals.html. Unfortunately, this didn't help. When adding logs I see that the code tries to access the provided dependency before it is being added. Any ideas what else I can try?
p
Heyhey, do you have an concrete example?
w
In DependencyProvider of module A:
Copy code
/**
   * @param Container $container
   * @return Container
   * @throws FrozenServiceException
   */
  public function addPreviewService(Container $container): Container
  {
    $this->getLogger()->info("addPreviewService()");
    $container->setGlobal(static::PREVIEW, function (Container $container) {
      return new MyPreviewService();
    });
    return $container;
  }
In factory of module B:
Copy code
try {
            $isPreview = $this->getProvidedDependency(MyDependencyProviderFromModuleA::PREVIEW)->isPreview();
            $this->getLogger()->error("Got PreviewService: " . $isPreview);
            return $isPreview;
        } catch (\Throwable $th) {
            $this->getLogger()->error("Failed to get PreviewService: " . $th->getMessage());
            return false;
        }
Log says:
Failed to get PreviewService: Spryker Kernel Exception
Container does not contain the called "PREVIEW"
You can fix this by adding the key "PREVIEW" to your "MyDependencyProviderFromModuleB" [
then a long time afterwards (even after my twig functions ran) the log says
addPreviewService()
p
Oh sorry, i meant it differently. Are these modules similar to Spryker modules? What you want to share between what? - because just setting sth global because you want to reuse code is actually quite against how the Spryker structure is build and meant to be used
w
Yeah that's why I'm asking. I found the article I mentioned above which seems quite fitting
To access this global dependency, inside your factory, call
$this->getProvidedDependency('Your service name')
. With this approach, you can define such dependencies once instead of defining them each time for each module that uses them.
Basically I have some logic that calculates a boolean value and I want to keep my code DRY so I want it in one module only. I tried to follow the structure that the Spryker modules have.
@plain-city-95899 any further ideas?
p
Tbh for me it is very hard to suggest something without knowing the exact background. If it is more like a Util with pure input => output without dependency to other services i would likely put it into “Service” application layer. But it is hard to say because it really depends case by case and normally we try to make as least as possible available global
So i think your step forward should be to check the “Service” application layers in the vendor/spryker/ modules to see examples.
w
Alright, will have another look. Thanks
h
You are trying in
ModuleB
to get dependency from
moduleA
. But you didn't execute
moduleA
so you don't have this dependency. You need to provide the same dependency in
moduleB
too. So, in all modules, where you use
MyPreviewService
you should provide this dependency first. In the
moduleB
you shouldn't have
MyDependencyProviderFromModuleA
usage, you can use
ModuleBDependencyProvider
only. Also, as @plain-city-95899 told you, you can introduce this module on
Service
layer and access to it using
$container->getLocator()->myPreview()->service()
instead of
new MyPreviewService()