Dependency Injection

About this theme: Passing arguments to an object’s method - PHP - SitePoint Forums | Web Development & Design Community

I have a class, that creates some data structure. And I know that this structure will be serialized with highest probability. For response on client, sending to external service and so on… I will create followed class (pseudocode)…

class Creator
{
    public function create()
    {
        //create
    }

    public function serialize()
    {
        $serializer = $this->getDIContainer()
            ->get(static::class, SerializerInterface::class);

        return serializer->serialize($this->create());
    }

    public function serializeToJSon()
    {
        $serializer = $this->getDIContainer()
            ->get(static::class, JSonSerializerInterface::class);

        return serializer->serialize($this->create());
    }

    public function serializeToXML()
    {
        $serializer = $this->getDIContainer()
            ->get(static::class, XMLSerializerInterface::class);

        return serializer->serialize($this->create());
    }
}

What I wouldn’t to do, every single time get data structure above and than serialize it with another class.

Was there a question somewhere in there? If so, what might that question be?

2 Likes

I’m not sure what your question is, but that isn’t DI. Using DI the class is not aware of the container.

In addition, having multiple serialisation methods in the same class like this is a bad idea. Funnily enough I used a very similar example here: https://r.je/single-responsibility-principle-how-to-apply

1 Like
 $this->getDIContainer()->get(static::class, SerializerInterface::class);

DI is relation of class(static::class) with service, that implements some interface(SerializerInterface::class). And concrete implementation placed in environment. How it realized, depends of application. So that is exactly DI. Try to understand, important thing is principle, not concrete form you learned in school.

Serialization methods are not in “same class”. Serialization methods in extern service(s) that used by this class. If serialization always bound to creating, than to have serialization methods in class is absolutelly optimal. Otherwise, you should always to create (and change) some specific code for serializing.

I am still not sure what you are asking here. If you have $this->getContainer() the class that contains the getContainer method is coupled to the container and you are not using DI.

Using DI in one of the methods above looks like this:

   public function serializeToJSon(JsonSerializer $serialiazer)
    {
        return serializer->serialize($this->create());
    }

Of course, as I also mentioned, such methods are a terrible idea anyway because they couple the class to the specific serialization methods.

Rather than $object->serialize() you should use $serializer->serialize($object) because then $serializer can be any serializer instance and you are not tied to only those implemented as serialize*() methods in the class itself.

Dependency injection would either inject dependencies in the method or in the constructor. As @TomB says, a class should not be aware of Dependency Injection. As soon as it does, it’s not Depency Injection anymore.

So regardless of whether that DIContainer is a proper DI container or not, it’s being treated as a Service Locator here. So no, this is not the Depencency Injection pattern at play in this example.

You can call an apple a pear, but it’s still an apple…

Tell it Java Spring authors.

Service locator not dependend of caller-class. So no, that is not Service Locator.

Same to you.

From wikipedia:

In software engineering, dependency injection is a technique in which an object receives other objects that it depends on. These other objects are called dependencies. In the typical “using” relationship the receiving object is called a client and the passed (that is, “injected”) object is called a service. The code that passes the service to the client can be many kinds of things and is called the injector.

The service is made part of the client’s state.[1] Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.

(emphasis on last paragraph mine)

https://en.wikipedia.org/wiki/Dependency_injection

This is not what is happening in your example. The class isn’t injected with services, it’s asking for services. Whatever it is, it is not Dependency Injection.