Factory used to create multiple objects

I have a module for account handling. this should provide basic functionality for my applications. this module will be added by composer to the projects.

What i want to reach is that i can easily extend the functionality and also the account attributes of its model easily. The account model has some basic attributes defined.

I have planned to just add a module (after the basic one) and let this overwrite the factory for the service and module. This works so far fine for the service (have a factory for the service and one for the account model).

My account model needs some services (others) too, thats why i thought i could solve this with a factory.

Now my problem is how can i use / call a factory in a service to get my models?

Is there a proper way or am i totally wrong with what i try to do?

Hello and welcome to our forums! :smiley:

There seems to be a misunderstanding here. A factory creates your service or model but your service or model does not know that there is a factory.

Please have a look at two features of laminas-servicemanager:

With this, you do not have to create factories as classes.

Hi, thanks for the reply. I’ve looked into that abstract factories but that did not deliver what i wanted.

What i have is
Service\Account
Model\Account
in my base model.

And the Service will create (or may let create) the Model\Account

What i wanted is that i can overwrite with a new Module the Service (which is easy by overwriting the factory) and the Model.
I thought when the Model\Account could be created within a factory, then i could overwrite it without touching the Service.

I guess when i want to extend the Model\Account only then i need to overwrite the Service to achieve that.

Please provide a code example for a better understanding. Thanks!

Service/Account

class Account extends AbstractModelService
{
    public function getModel($data = null)
    {
        // for a attribute model, here would be the initialization and attributes set before hydrating
        return $this->hydrate($data, new Model\Account());
    }
    ...
}

Model/Account

class Account extends AbstractDBRow
{
    protected $properties = [
        'id',
        'userName',
        'password',
        'salt',
        'isForcedPasswordChange',
        'baseRole',
        'isActive',
        'isDeleted',
        'divisionId',
        'gender',
        'foreName',
        'familyName',
        'email',
    ]
    ...

   public function getFullConfig()
   {
     // load custom config service to process file based configuration
   }
}

configuration

return [ 
    ...
    'divisionId'              => [
        'type'                     => 'smalltext',
        'appearance'               => 'select',
        'service'                  => 'DivisionService',
        'function'                 => 'getList',
        'serviceFunctionTargetKey' => 'translation'
    ],
];

im migrating from ZF2 to Laminas. I have sometimes in the configuration for the model also services which provide dynamically values like for divisionId (and this is user dependent)
There is a functionality that the model could provide the full configuration, it calls a service (my custom config service).
And there lies the real problem, it can call any service by configuration as it was (i know this is an anti pattern and should not be done). What i know is all services a model could use.

The models can be configured also dynamically dependent on a field (like ‘type’) and get for the same object different configuration and therefore different services. This are attribute models which have to load additionally attributes (by configuration) which are also models itself. These kind of models (like a contract model which shares a bunch of basic attributes and gets its specialization by attributes) are from outside one model and behave as that.

For extending the account model i need to overwrite the account service to reach that goal, which is ok.

For getting the final configuration of a model how do i manage that i a proper way when i have all the needed services by configuration? And these configuration can be different for the same object.
And sometimes the configuration are used without an object itself.

Another problem are the attribute models, they are initialized by configuration. So they need the AttributeService to get the proper attributes loaded.

Thats why i thought if there is something like a factory i could call for instantiate a model this functionality could be done there.

If I understand correctly, your service class is configurable.
If you want to overwrite or give another configuration to your service class, create a new factory and register it. In the factory you have access to the (merged) application configuration, the requested name, etc. This allows you to prepare your service class the way you want it and you can give your service class everything that is needed.

There is one service which does the processing of all attributes configuration of all models. This happens without knowing the models itself.

As clarification: Usually models are db row entries, sometimes with attributes loaded from additional tables. All services are configured as lazy services.

There is no such factory which i could request a model to be created in a service itself. So the service will instantiate these models by itself and has to be aware of all services a model need itself.
With this i see there 2 ways i could go:

  1. The config service has to know every service from the all the models who could be instantiated
    Thats sounds not like a good idea, every time i add a model, i need to adapt the config service too

  2. The service set the needed services when he instantiate a model. The configuration now needs always the according model to be able to get the needed services.
    This way the config service stays generic.

  3. I inject the container into the config service, but this is an anti pattern

Is there another way to solve this or do i need to go with 2) to get it right?