Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Help with Dependency Injection in MVC app

Zend Framework/Doctrine 2 application.:

/app
    /modules
        /blog
            /controllers
                /BlogController.php
            /domain
                /entities
                /services
                    /PostService.php
                /repositories

PostService is responsible for basic CRUD opterations, dealing directly with entities and the EntityManager to abstract the business and persistence logic out of my controllers.

If possible, I would like to keep my services as POPOs. What's the best way to access/inject the EntityManager in my service class? I'm new to DI, hence this question. The EntityManager is accessible as a bootstrap resource in my controllers.

Should I just write a abstract class for services to access the EntityManager? Should I write a class to instantiate my services, injecting the EntityManager via the constructor/setter?... which would involve an interface for my services. Should I use a DI framework? If so, which one and how?

Or is there another, better way to do this?

I have done reading on dependency injection but still don't fully grasp it in this context.


Update (12th Jan 2011)

So this is my current working solution: I have an action helper called Resource, it is a helper for retrieving resources from the bootstrap, or you can manually added resources to it: http://pastie.org/1450851

$this->_helper->Resource('em'); // get EntityManager

Can someone please provide some insight into the performance impact of storing bootstrap resources locally within the helper class? Am I over doing it?
TODO: Refactor the resourcesMap out of the class.

And I have an action helper for loading services: http://pastie.org/1450855
TODO: Add checks before attempting to load the service.

Please provide some criticism on the above :)

like image 362
Cobby Avatar asked Jan 06 '11 05:01

Cobby


People also ask

How can dependency injection be resolved?

Resolve dependencies using IServiceProvider You can use the IServiceCollection interface to create a dependency injection container. Once the container has been created, the IServiceCollection instance is composed into an IServiceProvider instance. You can use this instance to resolve services.

What is dependency injection in .NET core MVC?

ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. For more information specific to dependency injection within MVC controllers, see Dependency injection into controllers in ASP.NET Core.

How do you perform a dependency injection?

The 4 roles in dependency injectionThe service you want to use. The client that uses the service. An interface that's used by the client and implemented by the service. The injector which creates a service instance and injects it into the client.


2 Answers

To keep my service layer separated from the rest of the application, I will often rely on my controllers to handle the injection. I have yet to break down and use a DI container, but the resource injector described here works perfect for passing the EntityManager around my application.

The EntityManager is instantiated on the bootstrap as a resource, and an ActionHelper will add it to the controller if the controller is asking for it. Then I'll pass it to service objects either using constructor injection or setter injection.

class MyController extends Zend_Action_Controller
{
    // A little different from O'Phinney's implementation. I'm adding
    // the resource named 'entitymanager' as the public property $em.
    public $dependencies = array(
      'entitymanager' => 'em'
    );

    public function myAction()
    {
       $service = new MyService($this->em);
       // or...
       $service = new MyService();
       $service->setEntityManager($em);
    } 
}

I do use an interface called IHasEntityManager as well.

If you don't want to make your controller responsible for building Service objects, you may want to look into a DI container like Symfony Dependency Injection.

like image 181
Bryan M. Avatar answered Oct 12 '22 22:10

Bryan M.


Ben Scholzen (@DASPRiD) has an example of a his own DI pseudo-framework in the source-code for his blog. He uses custom mappers for his persistence, which he passes to each service on service instantiation. But it seems like it would be easily modifiable to accept the Doctrine2 EntityManager instance instead.

like image 29
David Weinraub Avatar answered Oct 12 '22 22:10

David Weinraub