Skip to content
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

Support obtaining custom services from static methods #58

Open
rthideaway opened this issue Feb 15, 2021 · 1 comment
Open

Support obtaining custom services from static methods #58

rthideaway opened this issue Feb 15, 2021 · 1 comment

Comments

@rthideaway
Copy link

rthideaway commented Feb 15, 2021

I love the feature to define custom services in behat tests and then use them across Context(s). However I experienced the problem when they are not accessible from static methods. This make it unable to access any custom service from behat hooks like

  /**
   * Creates the test entities before the test suite starts.
   *
   * @BeforeFeature @sometest
   */
  public static function createTestEntities(): void {
     // Custom behat service is obviously not presented in drupal's container
     // and there is no way to access the plugin's one.
     $service_not_recognized = \Drupal::service('my_test.behat.service');
  }

Would it be possible to implement the way to obtain plugin's container to get the custom services from static methods as well? Or by some other way? That would be really really amazing. I searched for a way if I be able to get the container from static methods, but had no luck so far.

@bircher
Copy link
Member

bircher commented Jun 9, 2021

I think it would probably be possible. But I am not sure that it would not create more problems than it is worth.
If you call this new static get method then it would throw an exception when the container was not set before.
The same is true also with \Drupal::service() of course. So it may work, but it may not, using the container via non static methods means your code needs to live as a method on an initialized object.

That said if you want something like this then you can create a new context with the following code:


use Drupal\Core\DependencyInjection\ContainerNotInitializedException;
use NuvoleWeb\Drupal\DrupalExtension\Context\RawDrupalContext;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class StaticServiceContext extends RawDrupalContext
{

  protected static $staticContainer = NULL;
  
  public function setContainer(ContainerBuilder $container)
  {
    parent::setContainer($container);
    static::$staticContainer = $container;
  }

  public static function getStaticContainer() {
    if (static::$staticContainer === NULL) {
      throw new ContainerNotInitializedException('\StaticServiceContext::$container is not initialized yet.');
    }
    return static::$staticContainer;
  }
  
  public static function service($id) {
    return static::getStaticContainer()->get($id);
  }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants