Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Nacho Colomina Torregrosa
Nacho Colomina Torregrosa

Posted on • Edited on

     

Making a symfony third party bundle extensible

When developing an external component which can be used in other projects, we would want to make it extensible so other developers can add their own capabilities.

In this post I would like to share how to drive it when developing asymfony third party bundle. This is a short example and the idea can be extrapolated to other languages or frameworks.

Let's imagine we are developing a bundle which allows us to send notifications by using three channels:Email,Push notification andsms. Our bundle define an interface which looks like this:

interfaceNotificationInterface{publicfunctionsendNotification(array$data):bool;publicfunctiongetName():string;}
Enter fullscreen modeExit fullscreen mode

Each of our notifications handlers will look like this:

classEmailNotificationHandlerimplementsNotificationInterface{publicfunctionsendNotification(array$data):void{/* handler email notification. Throw an exception in         case on error */}publicfunctiongetName():string{return'email';}}
Enter fullscreen modeExit fullscreen mode

The other ones (sms and push) will look as email one but itssendNotification implementation would be different.

Now, It's time to tell our bundle to tag all services which implementsNofiticationInterface properly. To do it, we need to register it in our extension class (underDependencyInjection folder)

classMyBundleExtensionextendsExtension{/**     * @throws \Exception     */publicfunctionload(array$configs,ContainerBuilder$container){// ... load services from file (services.xml, services.yaml or services.php)$container->registerForAutoconfiguration(NotificationInterface::class)->addTag('my_bundle.notification');// other loads ....}}
Enter fullscreen modeExit fullscreen mode

Now, in our project, we can use symfonytagged_iterator shortcut to get aniterable holding all notification handlers. We can do it simply by binding a variable in ourservices.yaml file:

services:# default configuration for services in *this* file_defaults:autowire:true# Automatically injects dependencies in your services.autoconfigure:true# Automatically registers your services as commands, event subscribers, etc.bind:$notificationHandlers:!tagged_iteratormy_bundle.notification
Enter fullscreen modeExit fullscreen mode

Now, if we inject$notificationHandlers in any of our services we will have access to all notification handlers. If we would create a new notification handler, for instance,TelegramNotificationHandler, it would be tagged as the other ones since it would implementNotificationInterface and it would be available in$notificationHandlers iterable

With this, we follow theopen-closed principle since we can add other notification handlers without modifying the existing ones.

Tagged iterators are really useful to create central repositories of services which are easily accesible. In my recently published book, I use them to create an accesible collection of api operations. If you want to know more, you can find the bookhere

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I like the idea of long term learning. Keeping myself learning day by day and sharing knowledge with the community help to grow as a professional and also as a person.
  • Location
    Alicante, Spain
  • Education
    Polytechnic university of Valencia
  • Work
    Full Stack Developer. PHP/Symfony - Angular
  • Joined

More fromNacho Colomina Torregrosa

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp