Skip to content

Factory

Mauro Gadaleta edited this page Jun 28, 2023 · 2 revisions

Using a Factory to Create Services

Suppose you have a factory that configures and returns a new NewsletterManager object:

import NewsletterManager from './NewsletterManager'

class NewsletterManagerFactory {
    static createNewsletterManager() {
        let newsletterManager = new NewsletterManager()

        // ...

        return newsletterManager
    }
}

To make the NewsletterManager object available as a service, you can configure the service container to use the NewsletterManagerFactory.createNewsletterManager() factory method:

YAML
services:
    # call a static method
    app.newsletter_manager:
        factory: 
          class: './App/Email/NewsletterManager'
          method: 'createNewsletterManager'

    # OR

    # call a method on the specified service
    app.newsletter_manager_factory:
        class: ./App/Email/NewsletterManagerFactory

    app.newsletter_manager:
        factory:
          class: '@app.newsletter_manager_factory'
          method: 'createNewsletterManager'      
JS
let definition = new Definition()
definition.setFactory(NewsletterManagerFactory, 'createNewsletterManager')
container.setDefinition('app.newsletter_manager', definition)

// or

let definitionFactory = new Definition(NewsletterManagerFactory)
container.setDefinition('app.newsletter_manager_factory', definitionFactory)

let definition = new Definition()
definition.setFactory(new Reference('app.newsletter_manager_factory'), 'createNewsletterManager')
container.setDefinition('app.newsletter_manager', definition)

You can also send some arguments to the static method if needed

YAML
services:
    app.newsletter_manager:
        arguments: ['simple_string', '@another_service', '%package_reference']
        factory: 
          class: './App/Email/NewsletterManager'
          method: 'createNewsletterManager'
JS
let definition = new Definition()
definition.args = ['simple_string', new Reference('another_service'), new PackageReference('package_reference')]
definition.setFactory(NewsletterManagerFactory, 'createNewsletterManager')
container.setDefinition('app.newsletter_manager', definition)

Passing Arguments to the Factory Method

If you need to pass arguments to the factory method, you can use the arguments options inside the service container.

services:
    # ...

    app.newsletter_manager:
        factory:
          class: './App/Email/NewsletterManager'
          method: createNewsletterManager
        arguments: ['@templating']

Using Main to the Factory Method

If you need to have multiple classes in the same factory file you can use the main attribute:

services:
    # ...

    app.newsletter_manager:
        factory:
          class: './App/Email/NewsletterManager'
          method: createNewsletterManager
          main: NewsletterManagerFactory
export class NewsletterManager {}

export class NewsletterManagerFactory {
    static createNewsletterManager() {
        let newsletterManager = new NewsletterManager()

        // ...

        return newsletterManager
    }
}