Wednesday, September 11, 2013

Using the ServiceManager as an Inversion of Control Container (Part 1)

Intro:

In Zend Framework 1, it was difficult to follow best practices when it came to writing testable code. Sure, you could make testable models, but once you need those models in a controller, what do you do? Zend Framework 2 makes it much easier. In this post, I'll cover the basics of injecting a model into a controller.

Motivation:

The main goal here is to be able to wire up and configure your application from the highest level possible. Constructor injection + inversion of control makes it easy to determine which classes are dependent on other classes, and swapping classes with mocks or stubs is a breeze.

Prerequisites:
Begin by creating a new Buildingmodule, with its directory structure, similar to creating the Album module in the Getting Started guide.

To create objects, first let's take a look at what we are trying to get away from.

    $building = new \Building\Model\Building();

This is bad. At least in a controller, or another model. No more new anything (except maybe Exceptions...), no more hard-coded class names. Dependencies don't belong at this level of the code. Zend Framework 2's ServiceManager allows you to programmatically configure your dependencies. You should already be at least vaguely familiar with higher level dependency configuration from the ZF2 Getting Started guide, as this is how the AlbumController is configured, though it does a lot of stuff behind the scenes.

    $sm = $this->getServiceLocator();
    $building  = $sm->get('Building');

This approach is better, but you still don't want to put this in the controller. You should avoid pulling in classes using the ServiceManager anywhere except factories. Put another way, in general, $sm->get() does not belong in a controller or model, but does belong in Module.php's factories array, which I'll demonstrate further down. A class full of objects created this way has a lot of "soft dependencies", which are difficult to document and keep track of. Instead, to 'inject' a dependency into a class, it should be a parameter in the construction. Let's start by creating the BuildingController with a Building model as a dependency, which we'll learn how to inject shortly. I usually store dependencies as instance variables during construction and access them when needed with 'getters'. In this example, we are still instantiating a new ViewModel from within the controller. We'll fix this in Part 2, where we learn how to use the ServiceManager to create objects with runtime dependencies (such as the $variables parameter in the ViewModel construction)

 
<?php
#module/Building/src/Building/Controller/BuildingController.php
namespace Building\Controller;

use Zend\Mvc\Controller\AbstractActionController;

class BuildingController extends AbstractActionController
{
    protected $_building;

    public function __construct($building)
    {
        $this->_building = $building;
    }

    protected function _getBuilding()
    {
        return $this->_building;
    }
    protected function _getViewModel($variables=null)
    {
        #we'll fix this later
        return new \Zend\View\Model\ViewModel($variables);
    }
    public function indexAction()
    {
        $building = $this->_getBuilding();
        $building->addLayer('blue');
        $building->addLayer('red');
        $viewModel = $this->_getViewModel(array('building'=>$building));
        return $viewModel;
    }
}

The Application's ServiceManager is responsible for creating services (the model and controller are both services). Internally, when tasked with creating a service with a particular name, Building\Controller\Building for example, it runs canCreate("Building\Controller\Building"), which checks all of your aggregated config arrays. One of the places it checks by default is the array returned by the method getControllerConfig() in Module.php, if it exists. This is where we can add the factory closure for the model that the controller needs access to.

    #module/Building/Module.php excerpt
    public function getControllerConfig()
    {
        return array('factories' => array(
            'Building\Controller\Building' => function ($sm)
            {
                $building = $sm->getServiceLocator()->get('Building');
                $controller = new Controller\BuildingController(
                    $building, $viewFactory);
                return $controller;
            }
        ));
    }

Creating controllers is actually handled by the ControllerManager, a (sub)subclass of the main ServiceManager, and $usePeeringServiceManagers is set to false, which is why we need $sm->getServiceLocator()->get() here instead of just $sm->get(); it needs to retrieve the main ServiceManager to have access to the rest of the application's services.

In this controller, the constructor triggers the instantiation of the Building model. The model isn't actually created until the controller's constructor runs, since it is not a model being passed in, but a factory. The factory is a closure, a function without a name which can be saved as a variable. The ServiceManager sets services as 'shared' by default, meaning that the first time it is referenced, it calls the closure creating the object, and every time after that it simply returns the already instantiated object.

It is important to note that if the name of controller configuration (in this case Building\Controller\Building) is listed here, it cannot be defined somewhere else as well. For example, if it is in the $config['controllers']['invokables'] section in your module.config.php, the ServiceManager will try to 'invoke' it, that is, construct it with no arguments, and will fail. If you are following along with your code, check if this is the case now, and fix it if necessary. I'll wait.

Let's create the Building model as a simple class with no dependencies for now.

 
<?php
#module/Building/src/Building/Model/Building.php
namespace Building\Model;

class Building
{
    protected $_bricks=array();

    public function addLayer($color)
    {
        $bricks = array($color, $color, $color);
        $this->_bricks[] = $bricks;
    }

    public function getBricks()
    {
        return $this->_bricks;
    }

}

Because there are no dependencies or other required constructor arguments, we can define Building\Model\Building as an invokable in Module.php. The getServiceConfig() method is one of the aggregated configs that the ServiceManager checks to see which services it can create, and you should recognize it from the Getting Started guide.

 
    #module/Building/Module.php excerpt
    public function getServiceConfig()
    {
        return array(
            'invokables'=>array(
                'Building'=>'Building\Model\Building',
            ),
        );
    }


ZF2 provides multiple ways of doing a lot of things. It is possible, for example, to separate the configuration into multiple files, which might be advisable once your wiring starts getting complicated. The factories can be their own classes which implement 'FactoryInterface' instead of closures defined in the config array.

But, we are done for now. Control has now been inverted. We are injecting a dependency (Building) into a controller using the ServiceManager, and all of our wiring and configuration is in one place, Module.php.

If you want to test it out now and get something running, read the rest of this post. Otherwise, check out Part 2 to learn how to inject a dependency where each instance needs to be distinct and have its own configuration, e.g. using a $model->findAll() or similar.

You'll need to create a view

 
<?php
#module/Buidling/view/building/building/index.phtml
?>
<table >
<?php
foreach ($this->building->getBricks() as $key=>$layer)
{
    echo '<tr>';
    foreach ($layer as $brick)
    {
        echo '<td style="text-align:center; border:1px solid black;'.
            ' background-color:' . $brick . ';">';
        echo $brick;
        echo '</td>';
    }
    echo '</tr>';
}
?>
</table>

And then be sure to set up a route to /building so it is accessible.
 
<?php
#module/Building/config/module.config.php
return array(
    'router' => array(
        'routes' => array(
            'building' => array(
                'type'    => 'segment',
                'options' => array(
                    'route'    => '/building[/:action]',
                    'constraints' => array(
                        'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                    ),
                    'defaults' => array(
                        'controller' => 'Building\Controller\Building',
                        'action'     => 'index',
                    ),
                ),
            ),
        ),
    ),
    'view_manager' => array(
        'template_path_stack' => array(
            'building' => __DIR__ . '/../view',
        ),
    ),
);

Don't forget the getConfig() and getAutoloaderConfig() methods in your Module.php.

    
    #module/Building/Module.php excerpt
    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\ClassMapAutoloader' => array(
                __DIR__ . '/autoload_classmap.php',
            ),
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }

    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

Finally, just go to http://localhost/building, and you should see a simple empty page with the layers we added.
Check out https://github.com/rwilson04/zf2-dependency-injection/tree/part1 for the code.

Here's the link to Part 2 again.

Comments are welcome.

65 comments:

  1. Nicely explained!
    Keep up the good work :)

    ReplyDelete
  2. Big thank you for this! It clarified me some things as I begin with ZF2.
    I'm running into part2 :)

    ReplyDelete
  3. Inversion boots, otherwise known as gravity boots, allow for complete, inverted suspension from a stabilized horizontal bar or inversion rack. gravity boots benefits

    ReplyDelete
  4. Great survey, I'm sure you're getting a great response. 192-168-i-i.com

    ReplyDelete
  5. A very awesome blog post. We are really grateful for your blog post. You will find a lot of approaches after visiting your post. impactor error fix

    ReplyDelete
  6. What is the best free AppStore for iOS. Try Tutuapp, the best app and game platform for iPhone.

    ReplyDelete
  7. At that point Body Champ IT8070 inversion therapy table is the thing that you have to purchase. This device certainly fathoms back issues that doctors and advisors have supported the thing. gravity boots vs inversion table

    ReplyDelete
  8. Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I'll be subscribing to your feed and I hope you post again soon. Big thanks for the useful info. hoverwatch coupon code

    ReplyDelete
  9. Great article Lot's of information to Read...Great Man Keep Posting and update to People..Thanks Social Media Management Strategies

    ReplyDelete
  10. Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I'll be subscribing to your feed and I hope you post again soon. Big thanks for the useful info. write for us tech blog

    ReplyDelete
  11. I found your this post while searching for some related information on blog search...Its a good post..keep posting and update the information. vpn 추천

    ReplyDelete
  12. visite our sit for more information about us
    EZTV Proxy

    ReplyDelete
  13. There are a lot of blogs over the Internet. But I can surely say that your blog is amazing in all. It has all the qualities that a perfect blog should have. https://wifiextender.eu/

    ReplyDelete
  14. You made such an interesting piece to read, giving every subject enlightenment for us to gain knowledge. Thanks for sharing the such information with us to read this... algebra calculator online

    ReplyDelete
  15. Thanks for your insight for your fantastic posting. I’m exhilarated I have taken the time to see this. It is not enough; I will visit your site every day. security cameras

    ReplyDelete
  16. Hi! This is my first comment here so I just wanted to give a quick shout out and say I genuinely enjoy reading your blog posts. Can you recommend any other Fashion Write For Us blogs that go over the same topics? Thanks a ton!
    Visit our blog too Fashion Write For Us

    ReplyDelete
  17. Nice Post...
    Optimize PC Performance With HP Support Assistant
    HP computer or laptop may sometime work slow. To enhance the computer speed, it is required to download and install HP Support Assistant application. It is the software used to optimize your PC and help improve its performance. In many HP computers and laptops, the application comes pre-installed for the better performance of the device. However, using HP Support Assistant is the easy way to keep your PC running smoothly without any interruption. If it is not installed in your HP computer device, contact us via helpline number. We will guide you properly and once you scan your PC using such application, it will help maintain your system.

    ReplyDelete
  18. I’m Facing Issues With My Microsoft Office Setup
    Not able to finish office setup? It can be an issue with your System or installation procedure. Make sure the device on which you are trying to install office is compatible with your version of Microsoft Office. You can check the minimum system requirements for your Office product on the Microsoft office.com official website. Also, check if you have enough storage on your hard disk to install the Office suite. It can also be an issue with your internet. Try switching to another internet or using WiFi for a better experience.
    Sometimes when you are installing Office, you get an error. To fix the error, you can click on the Learn More option available on the page where the error has occurred. There you will find information about how you can troubleshoot this error.
    office.com/setup
    www.office.com/setup

    ReplyDelete
  19. There are alot of blogs over the internet but i can surely say that your blog is nice in all timemobiles price in pakistan

    ReplyDelete
  20. It explains that it does lead to negative impacts by leading to a shift on the preferences of spending funds. buy personal statement online

    ReplyDelete
  21. Try multiple variant of hashtags such as brand specific hashtags, general hashtags, and trending hashtags, to get noticed in searches. check this link right here now

    ReplyDelete
  22. If your account is public (as is by default), anyone can see your Boost Twitter Visibility, irrespective of whether they are following you. No, they can not see your tweets in the news feed. They can only see your tweet if they go to your page and read down through your tweets.

    ReplyDelete
  23. Excellent write up, never seen such a amazing, well structured and informative content on the web. Keep sharing. But if you want to read such kind of informative articles or access huge academic database, login at research proposal writing service rendered by SourceEsssay

    ReplyDelete
  24. I am searching for the this topic info many year and trust me. My need fulfill after reading your this post. Happy to be learning random ideas and knowledge from here about each subject. I am also content writer but i cant write like this information, If you no any problem. Can you suggest me. I felt like an expert in this field. I have several articles on these topics posted on my site. Thanks buy assignment online - accounting assignment help - statistics assignment help

    ReplyDelete
  25. Astrologyswami.com is the official website of Aghori Tantrik Jitesh Bhai Ji. Tantrik Ji is the well known personality today who is guiding people for their better life. Vashikaran specialist near me | Vashikaran Specialist |Vashikaran Specialist Aghori Baba | Vashikaran Specialist in Tamil Nadu

    ReplyDelete
  26. Somatropin is the generic name of the drug sold under the brand name Ototropin.Various brands of this medication are used for the treatment of one of the following medical conditions: growth failure, growth hormone deficiency. Buy somatropin injection from official website Mediseller.

    ReplyDelete
  27. Thanks for sharing the informative content! We provide you the best solutions to your rr.com Email Login issue and other roadrunner email services issue. So if you are facing any email login issues, you can definitely come to us. On our website, you’ll find the solutions for Roadrunner, TWC, and Spectrum email.

    ReplyDelete
  28. SA 8000 is a social accountability management system standard that helps an organization to apply and develop socially accountable practices in the workplace. This voluntary standard is developed based on the ISO standard’s requirements and the guidelines of national labour laws, the UN Declaration of Human Rights, and international human rights norms. SA 8000 Certification in Hong Kong | Social accountability | Focused on employee welfare | covers legal requirements | Contact: enquiry@iascertification.com. Call @ +6531591803

    ReplyDelete
  29. Wow! It is a completely different topic. Great choice of Topic! You can apply for a Turkey visa online. You can get your Turkey Visa in just 1 hour by selecting the express processing type. It only takes 5 minutes to apply for an electronic visa Turkey. Apply Online.

    ReplyDelete
  30. Thank you for sharing your info; I really appreciate your efforts and I will be waiting for your next post. Thanks once for sharing. Also visit fce okene diploma admission requirements

    ReplyDelete
  31. Hire our Business Law Assignment Help for your business management dissertation work. The online assignment helps allow you to do your work on time. Moreover, our subject matter experts perform intense research on the subjects from genuine resources to ensure that you get quality work.

    ReplyDelete
  32. IAS is one of the ISO 22000 Certification Bodies in Asia. We provide ISO Food Safety Management System Certification Service for more than 13 years in an effective and consistent manner. ISO FSMS Certification helps build strong FSMS and attract new business opportunities. In short, this certification assures food safety and guarantees customer’s belief. ISO 22000 Certification in Philippines | Short Audit and Reports | certificate in record time | Simple-Transparent | Contact:enquiry@iascertification.com. Call @ +6531591803

    ReplyDelete
  33. Get Technical Support from 'Support For Emails' to get solutions for all your email technical issues whether it's Microsoft Outlook email, sbcglobal email, Microsoft office 365 issues, or others. Browse the website of supportforemails to get reliable support services in very reasonable prices.
    Outlook not opening

    ReplyDelete
  34. Microsoft office solution provider.
    We offer you the best Microsoft outlook support services. Get a Microsoft outlook support number for managing your email accounts to offer you a complete Microsoft outlook solution for any type of email-related issue, our team of technical experts is here to provide you with the best customer support.Microsoft Outlook Support Number

    ReplyDelete
  35. I feel extremely cheerful to have seen your post. I found the most beautiful and fascinating one. I am really extremely glad to visit your post.
    Vlone hoodie

    ReplyDelete
  36. Find snow blowers at Lowe's today. Free Shipping On Orders $45+. Shop Best 2 stage snow blower and Best 2 stage snow blower under $1000 and a variety of outdoors products online at power tools.

    ReplyDelete
  37. This comment has been removed by the author.

    ReplyDelete
  38. Keep sharing such a great article! Are you stuck with your assignment? GoAssignmentHelp is one of the best Artificial Intelligence Assignment Help service providers that provide best Computer Network Assignment Help to those students who face these issues and write Business Statistics Assignment Help and score good grades.

    ReplyDelete
  39. Positive site, where did u come up with the information on this posting? I'm pleased I discovered it though, ill be checking back soon to find out what additional posts you include.

    my assignment help|
    essay typer|
    do my assignment|
    assignment help sydney|

    ReplyDelete
  40. messages for birthday wishes At New Happy Birthday Wishes Find the Perfect Happy Birthday line Quote You may check our best collection of birthday wishes.

    ReplyDelete
  41. It is a good site,Thank you.. Obtain the Indian e-Medical visa online via Indian visa website. Indian Medical Visa is a travel permit approved by the Government of India for persons who wish to come to India for medical treatment. Indian e-Medical visa cost depends on your nationality.

    ReplyDelete
  42. Bad Bunny Merch Hats
    Bad Bunny Hoodies
    Bad Bunny Merch Collection Fans
    ✅ Bad Bunny Hoodie, Bad Bunny T Shirt, Hats, and Backpacks.
    ✅ Get High Quality Products ✅ Amazing Discount.

    ReplyDelete
  43. The new report by Expert Market Research titled, ‘Global Pulses Market Report and Forecast 2022-2027’, gives an in-depth analysis of the global Pulses Market, assessing the market based on its segments like type, growth, demand, end use and major regions like Europe, Asia Pacific, North America, Middle East & Africa and Latin America. The report tracks the latest trends in the industry and studies their impact on the overall market upcoming years. The growth of the global pulses market is driven by the increasing health awareness among people all over world. The increasing popularity of food products with cholesterol free and high protein is expected to propel the demand for pulses forward. The presence of antioxidants, vitamins, complex carbohydrates, and folate is likely to aid in the growing consumption of pulses. The major players in the market are Adani Group, Nestle SA, Groupe Danone, Vitasoy International Holdings Ltd, Reckitt Benckiser Group Plc (RB), Coca-Cola Co, Abbott Laboratories Inc., General Mills Inc., Blue Diamond Growers, and a few others. The report covers the market shares, capacities, expansions, investments and acquisitions, among other latest developments of these market players. Expert Market Research provides market intelligence across a range of industry verticals which include Pharmaceuticals, Food and Beverage, Health, Chemical and Materials, Energy and Mining. For more information, You can check our website.

    ReplyDelete
  44. For college students enrolled in botany courses, the sight of a large stack of homework papers is the most terrifying. Assignments entail a significant quantity of work that students are unable to complete on their own. This approach is used in most institutions across the world to assess students' topic understanding. To accomplish so, the professors in charge assign the most difficult topics to the pupils in order to get the most out of them. As a result, they frequently fail to match the paper's criteria and lose interest in the subject. Our effective botany assignment help, on the other hand, answers all of your questions correctly. Our top-notch assignment answers make it simple for you to get good scores.

    ReplyDelete
  45. Authentic Vlone store to buy Vlone Shirts, vlone hoodies and much more. Vlone Garments, Vlone Official

    ReplyDelete

  46. Our work isn't done once you've turned in your assignment. Assignment Help
    assists you in getting the finest assistance possible to make sure that any rework you require on your project may be handled immediately away. Before you ultimately submit the assignment on your university site, it's important to make sure you're still pleased with it.

    ReplyDelete
  47. Thanks for Sharing this post. The assignment help Hong Kong you have been looking for is here. Click here to find out the range of disciplines we would be happy to help you with.

    ReplyDelete
  48. I am very grateful to you for sharing this wonderful topic with us. It is very informative for me. genyoutube

    ReplyDelete
  49. Know All Possible Reasons Why Is My Instagram Not Working
    It would be good to determine all possible reasons Why Is My Instagram Not Working
    . The main reasons can be poor internet connection on your mobile device and the usages of outdated Instagram application. To get rid of such problems, you have to get the latest version of your mobile device and then you have to rectify your internet issue and make sure to have a strong internet connection. For more information, you have to go to the official help center where you can get the right guidelines.

    ReplyDelete
  50. You may not realize it, but the Custom hang tags you choose is crucial to selling your
    products and creating your brand. It is the first thing consumers see and is your brand's
    ambassador, just like an employee name tag, except nicer. That is why every element, from
    colour and shape to the information and photos you put on it, must be designed with as
    much attention as your collection

    ReplyDelete
  51. We'll then recommend packaging bags that best meet your needs. CustomShipping bags
    and custom mailers are affordable, eco-friendly, stylish personalized mailing bags
    made of poly are an effective device in your marketing plan.

    ReplyDelete
  52. Interesting effort for sharing these ideas; I learned new great stuffs from your blog and I also look forward to learning more from your next publication of knowledge and ideas. Thanks so much for sharing. futa jamb cut off mark

    ReplyDelete
  53. Thank you for sharing this Helpful blog. Appliances

    ReplyDelete
  54. This comment has been removed by the author.

    ReplyDelete
  55. Are you struggling with your academic assignments and looking for reliable assistance? Look no further! In this blog, we will explore the best assignments help in Australia, and how it can positively impact your academic journey.

    ReplyDelete
  56. When you have errands to do outdoors and have a baby to take care of, at the same time, you know that you are up for a challenge. pet articles As guilty as you are for leaving your beloved pet all alone at home, it is perhaps equally guilty indulging itself in some cute and not so cute antics.

    ReplyDelete
  57. "Your research papers help service is a true academic ally for students seeking guidance in the world of scholarly writing. The dedication to providing assistance in crafting well-researched and meticulously written papers is evident. research papers help

    ReplyDelete
  58. The primary objective here is to have the option to wire up and design your application from the most elevated level conceivable. Constructor infusion + reversal of control makes it simple to figure out which classes are reliant upon different classes, and trading classes with derides or nails is a breeze.
    truck driving accidents

    ReplyDelete