-
-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handling factory methods using instantiateWith
#388
Comments
Hi @1ed I think you raise a fair point here. IMO the cleanest way to handle this would be to split the Instantiator and to introduce something like an |
Agreed this is a fair point and splitting the class. Some thoughts:
|
1- About BC all following options will apply to hydrator and not on instantiator anymore: public function initialize(): self
{
return $this->instantiateWith(
(new Instantiator())->alwaysForceProperties()
);
} and we need to deprecated all setters for these options in the instantiator. Also I may be wrong, but I think there is no valid use case to use 2- agreed, and the hydrator should have all the setters for the options mentioned above. 3- IMO this should be handled the same way than now, given |
Thinking // customize the hydrator
public function initialize(): self
{
return $this->hydrateWith(function(Hydrator $hydrator) {
// $hydrator is the "default" hydrator service configured by bundle config
// this allows us to inject property_accessor and property_info into it
return $hydrator
->alwaysForceProperties()
->allowExtraAttributes()
; // clones the hydrator
});
// alternative to above
return $this->hydrateWith(Hydrator::FORCE_PROPERTIES | Hydrator::ALLOW_EXTRA);
// complete control
return $this->hydrateWith(function(MyObject $object, array $remainingAttributes) {
$object->someRichMethod($remainingAttributes['foo'], $remainingAttributes['bar']);
return $object;
});
} |
And public function initialize(): self
{
return $this->instantiateWith(Instantiator::WITHOUT_CONSTRUCTOR);
// or use a factory method
return $this->instantiateWith([MyObject::class, 'factoryMethod']);
// complete control:
return $this->instantiateWith(function(array &$attributes) {
$object = new MyObject($attributes['foo'], $attribtues['bar']);
// required if not using a custom hydrator
unset($attributes['foo'], $attributes['bar']);
return $object;
});
} I think that's really the only custom config you'd need to make for the instantiator, or am I missing something? In the bundle config, we'd only need boolean for the default instantiation mode: with constructor (default) or without. |
I like the bitwise configurations :) for the instantiator:
for the hydrator: don't we also need |
Agreed, don't see a way around it currently either. If customizing both, you could do everything in the instantiator and somehow disable the hydrator.
Yep, these just couldn't be configured via bits |
@kbond I kinda remember that you said we were stuck here, but I'm not 100% sure? how would this integrate with Foundry v2 architecture? |
I think this is at least partially solved. I think the remaining issue is with circular dependencies - two entities that require each other. @1ed, sorry for the late response but is this issue still relevant? |
I'm closing this stale issue, feel free to reopen it, if it is still relevant |
Hi, I have big entity with lots of attributes. This Entity has different instantiation logic based on the usage, so I use factory methods which have some validation logic. I would like to use these methods in foundry factories too, so I use
I'm wondering are there any other option? Because, in this case the other entity properties never initialized based on the attributes. I don't want to call all the setters on the entity manually. Using the
Instantiator
class is not possible because it will not call the factory method on the entity, but it always instantiates the subject by itselffoundry/src/Instantiator.php
Line 43 in 321abbe
Maybe we should split this class into 2, one for instantiate and one for initialize the subject, or simply just allow to call factory methods instead of the constructor like:
The text was updated successfully, but these errors were encountered: