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

Question: How to handle instances of the same class with different purpose? #133

Closed
k00ni opened this issue Aug 11, 2017 · 4 comments
Closed

Comments

@k00ni
Copy link

k00ni commented Aug 11, 2017

I have the following example code:

class HttpHandler 
{
   public function __construct(
        ParameterBag $requestCookies, 
        ParameterBag $responseCookies
   ) {
      ...
   }
}

The class is about HTTP handling, basically. The constructor receives two instances of the same class, each with its own purpose. There are other classes which also require and work with $requestCookies and $responseCookies.

I want these two to be unique and be reuseable, because i am working with a MVC approach and handle cookies on different levels (e.g. Controller, Auth). After they were created, they HAVE to be reused. Btw, i am strictly against usage of super globals or singleton variables.

Approach 1

Create dummy subclasses of ParameterBag: RequestCookies and ResponseCookies, which extend ParameterBag basically.

This would bloat my class base, furthermore these dummy subclasses would have no value except being part of a workaround.

The according code would be:

class HttpHandler 
{
   public function __construct(
        RequestCookies $requestCookies, 
        ResponseCookies $responseCookies
   ) {
      ...
   }
}

Approach 2

Write a custom value for instanceOf to force using a certain instance, like:

$dice->addRule('_RequestCookies', array(
    'shared' => true,
    'instanceOf' => 'ParameterBag'
);

$dice->addRule('_ResponseCookies', array(
    'shared' => true,
    'instanceOf' => 'ParameterBag'
);

$dice->addRule('Backbone\User\Auth', array(
    'shared' => true,
    'instanceOf' => new \Backbone\User\Auth(
        $this->dice->create('Saft\Rdf\CommonNamespaces'),
        $this->dice->create('Saft\Rdf\RdfHelpers'),
        $this->dice->create('Symfony\Component\HttpFoundation\Session\Session'),
        $this->dice->create('_RequestCookies'),
        $this->dice->create('_ResponseCookies'),
        $this->dice->create('Knorke\ResourceGuyHelper'),
        $this->dice->create('Backbone\User\User')
    )
));

The problem with this approach is, that it "calls" dice immediately, therefore real instances get created. That is problematic if i am in a test environment and what to injection further/different rules before.


Which rule(s) do i have to apply, so that i get instances which are shareable/reusable?

Help is much appreciated
Thanks

@k00ni
Copy link
Author

k00ni commented Aug 11, 2017

It seems named instances do the job just fine: https://r.je/dice.html#example3-6 👍

@TRPB
Copy link
Member

TRPB commented Aug 11, 2017

Yes, named instances are the best solution for this. It's basically what you have in approach 2, but you'd also create a named instance for Backbone\User\Auth.

@k00ni
Copy link
Author

k00ni commented Aug 11, 2017

Hi, thanks for the reply. The following code snippet contains my solution:

// Auth
$this->rules['Backbone\User\Auth'] = array(
    'shared' => true,
    'constructParams' => array(
        array('instance' => 'Saft\Rdf\CommonNamespaces'),
        array('instance' => 'Saft\Rdf\RdfHelpers'),
        array('instance' => '_Session'),
        array('instance' => '_RequestCookies'),
        array('instance' => '_ResponseCookies'),
        array('instance' => 'Knorke\ResourceGuyHelper'),
        array('instance' => 'Backbone\User\User')
    )
);

// ParameterBag instance representing request cookies
$this->rules['_RequestCookies'] = array(
    'shared' => true,
    'instanceOf' => 'Symfony\Component\HttpFoundation\ParameterBag'
);

// entries are of type Cookie and are subject to be send in Response
$this->rules['_ResponseCookies'] = array(
    'shared' => true,
    'instanceOf' => 'Symfony\Component\HttpFoundation\ParameterBag'
);

// Session
$this->rules['_Session'] = array(
    'shared' => true,
    'instanceOf' => 'Symfony\Component\HttpFoundation\Session\Session',
);

@k00ni k00ni closed this as completed Aug 11, 2017
@garrettw
Copy link

Now, all we need to add to make this easier is the ability to specify constructor params by name and not solely argument position.

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

3 participants