SyliusCon 2025 in Lyon
Join Us!
LogoLogo
🛣️ Roadmap💻 Sylius Demo💬 Community Slack
  • Sylius Documentation
  • Sylius Plugins
  • Sylius Stack
  • Sylius Stack Documentation
  • Getting started
  • Cookbook
    • How to customize your admin panel
      • Basic operations
      • Customizing your grids
      • Customizing the logo
      • Customizing the menu
      • Configuring the security access
      • Customizing the page titles
    • How to use in a DDD architecture
      • Architecture overview
      • Resource configuration
      • Basic operations
      • Operation using a grid
  • Admin UI
    • Getting started
  • Bootstrap Admin UI
    • Getting started
  • Resource
    • Resource Bundle documentation
      • Installation
      • Create new resource
      • Configure your resource
      • Configure your operations
      • Validation
      • Redirect
      • Resource factories
      • Providers
      • Processors
      • Responders
      • Legacy Resource Documentation
        • Configuration
        • Services
        • Routing
        • Forms
        • Getting a Single Resource
        • Getting a Collection of Resources
        • Creating Resources
        • Updating Resources
        • Deleting Resources
        • Configuring a state machine
        • Configuration Reference
  • Grid
    • Grid Bundle documentation
      • Installation
      • Creating your first grid
      • Configuring Fields
      • Field types
      • Creating a custom Field Type
      • Creating a custom Action
      • Creating a custom Bulk Action
      • Filters
      • Creating a custom Filter
      • Advanced configuration
      • Configuration Reference
  • 🍀Twig Extra
    • Getting started
  • 🌱Twig Hooks
    • Getting started
    • Passing data to your hookables
    • Making your hookables configurable
    • Autoprefixing feature
    • Composable Layouts with a predictable structure
    • Advanced
      • Ergonomic work with hooks
      • Metadata objects
      • Multiple hooks inside a single template
      • Overriding hookables
Powered by GitBook
LogoLogo

Developer

  • Community
  • Online Course

About

  • Team

© 2025 Sylius. All Rights Reserved

On this page
  • Default factory for your resource
  • Inject the factory in your service
  • Define your custom factory
  • Use your custom method
  • Pass arguments to your method
  • Use a factory without declaring it
  • Use a callable for your custom factory

Was this helpful?

Edit on GitHub
  1. Resource
  2. Resource Bundle documentation

Resource factories

PreviousRedirectNextProviders

Last updated 2 months ago

Was this helpful?

Resource factories are used on Create operations to instantiate your resource.

Default factory for your resource

By default, a resource factory is defined to your resource Sylius\Component\Resource\Factory\Factory.

It has a createNew method with no arguments.

Inject the factory in your service

If you are using Symfony autowiring, you can inject the resource factory using the right variable name.

src/MyService.php
namespace App;

use Sylius\Resource\Factory\FactoryInterface;

final class MyService
{
    public function __construct(
        private FactoryInterface $bookFactory,
    ) {}
}

In this example, the app.factory.book will be injected in your $bookFactory

You can find the variable name using this debug command:

$ bin/console debug:autowiring app.factory.book

Define your custom factory

src/Factory/BookFactory.php
declare(strict_types=1);

namespace App\Factory;

use App\Entity\Book;
use Sylius\Resource\Factory\FactoryInterface;

final class BookFactory implements FactoryInterface
{
    public function createNew(): Book
    {
        $book = new Book();
        $book->setCreatedAt(new \DateTimeImmutable());
        
        return $book;
    }
}

Configure your factory

config/services.yaml
services:
    App\Factory\BookFactory:
        decorates: 'app.factory.book'

Use your custom method

src/Factory/BookFactory.php

declare(strict_types=1);

namespace App\Factory;

use App\Entity\Book;
use Sylius\Resource\Factory\FactoryInterface;
use Symfony\Component\Security\Core\Security;

final class BookFactory implements FactoryInterface
{
    public function __construct(private Security $security) 
    {
    }

    public function createNew(): Book
    {
        return new Book();
    }
    
    public function createWithCreator(): Book
    {
        $book = $this->createNew();
        
        $book->setCreator($this->security->getUser());
        
        return $book;
    }
}

Use it on your create operation

src/Entity/Book.php

declare(strict_types=1);

namespace App\Entity\Book;

use Sylius\Resource\Metadata\AsResource;
use Sylius\Resource\Metadata\Create;
use Sylius\Resource\Model\ResourceInterface;

#[AsResource(
    operations: [
        new Create(
            path: 'authors/{authorId}/books',
            factoryMethod: 'createWithCreator',
        ),
    ],
)
class Book implements ResourceInterface
{
}

Pass arguments to your method

You can pass arguments to your factory method.

3 variables are available:

  • request: to retrieve data from the request via Symfony\Component\HttpFoundation\Request

  • token: to retrieve data from the authentication token via Symfony\Component\Security\Core\Authentication\Token\TokenInterface

  • user: to retrieve data from the logged-in user via Symfony\Component\Security\Core\User\UserInterface

src/Factory/BookFactory.php

declare(strict_types=1);

namespace App\Factory;

use App\Entity\Book;
use Sylius\Resource\Doctrine\Persistence\RepositoryInterface;
use Sylius\Resource\Factory\FactoryInterface;

final class BookFactory implements FactoryInterface
{
    public function __construct(private RepositoryInterface $authorRepository) 
    {
    }

    public function createNew(): Book
    {
        return new Book();
    }
    
    public function createForAuthor(string $authorId): Book
    {
        $book = $this->createNew();
        
        $author = $this->authorRepository->find($authorId);
        
        $book->setAuthor($author);
        
        return $book;
    }
}

Use it on your create operation

src/Entity/Book.php

declare(strict_types=1);

namespace App\Entity\Book;

use Sylius\Resource\Model\ResourceInterface;
use Sylius\Resource\Metadata\AsResource;
use Sylius\Resource\Metadata\Create;

#[AsResource(
    operations: [
        new Create(
            path: 'authors/{authorId}/books',
            factoryMethod: 'createForAuthor',
            factoryArguments: ['authorId' => "request.attributes.get('authorId')"],
        ),
    ],
)
class Book implements ResourceInterface
{
}

Use a factory without declaring it

You can use a factory without declaring it on services.yaml.

src/Entity/Book.php

declare(strict_types=1);

namespace App\Entity\Book;

use App\Factory\BookFactory;
use Sylius\Resource\Model\ResourceInterface;
use Sylius\Resource\Metadata\AsResource;
use Sylius\Resource\Metadata\Create;

#[AsResource(
    operations: [
        new Create(
            path: 'authors/{authorId}/books',
            # Here we declared the factory to use with its fully classified class name
            factory: BookFactory::class,
            factoryMethod: 'createForAuthor', 
            factoryArguments: ['authorId' => "request.attributes.get('authorId')"],
        ),
    ],
)
class Book implements ResourceInterface
{
}

Use a callable for your custom factory

src/Factory/BookFactory.php

declare(strict_types=1);

namespace App\Factory;

use App\Entity\Book;

final class BookFactory
{    
    public static function create(): Book
    {
        return new Book();
    }
}
src/Entity/Book.php

declare(strict_types=1);

namespace App\Entity\Book;

use App\Factory\BookFactory;
use Sylius\Resource\Metadata\AsResource;
use Sylius\Resource\Metadata\Create;
use Sylius\Resource\Model\ResourceInterface

#[AsResource(
    operations: [
        new Create(
            factory: [BookFactory::class, 'create'], 
        ),
    ],
)
class Book implements ResourceInterface
{
}

It uses the component.

Resource factories
Default factory for your resource
Inject the factory in your service
Define your custom factory
Use your custom method
Pass arguments to your method
Use a factory without declaring it
Use a callable for your custom factory
Symfony expression language