Closed Mikulas closed 8 years ago
Could you elaborate on the second possible solution? Sadly, I don't understand the beginning at all. However, I'm plased that such advanced things are almost possible :)
Also the last two solutions have the added benefit of removing
public function __construct(IEntity $entity, PropertyMetadata $propertyMetadata);
which currently makes it hard to extend.
I haven't really though it through with the injected container factory. I am however very much in favour of
call to protected method that would by default do the same as now
I will prepare a patch just to illustrate the point (without any expectations of merge-ability).
such advanced things are almost possible
Yeah very much so! GJ :)
Also the last two solutions have the added benefit of removing
Yes, removing the needed constructor parameters would be great!
Alright this is what I hacked up quickly: https://github.com/nextras/orm/compare/master...Mikulas:preview/container-factory
IInstantiableProperty
is not a great name, but other that that it would greatly improve the usability of IProperty
.
What about:
if (!is_subclass_of($class, IPropertyFactory::class, TRUE)) {
return $class::create(...);
} else {
return $class(...);
}
by passing this as the first arg the factory will have an access to injected dependencies.
Or what if IProperty
had public static create(IEntity, PropertyMetadata)
? (It would have to anyway to allow this construct). I've though of that, but there is (as of php < 7) no guarantee what the method returns, there would have to be an instanceof
check in private initProperty
.
I'm not sure that would solve the original issue though. What I think I need is
class MyEntity extends Orm\Entity {
protected function createPropertyContainer(PropertyMetadata $metadata) {
if ($metadata->name === 'address') {
return new PostgresTypePropertyProxy($this, $metadata, … my additional args …);
}
return parent::createPropertyContainer($metadata);
}
}
I see, you desperately want to construct the property in context of the entity. In such case, I see no use for another interface. Let's just extract that functionality into own method. Ok?
Luckily @JanTvrdik found out I already can get everything from $metadata
, so we don't really need this interface patch anymore to implement this.
I'm sending a patch with createPropertyContainer
though.
Thanks.
I'm refactoring implementation of postgres composite types in our app for the third time. Final solution I've arrived at is generic
PostgresCompositeType
class that can parse and be serialized into pg composite type. Those are linked withIEntities
viaPostgresTypePropertyProxy
which implementsIPropertyContainer
.This
PostgresTypePropertyProxy
is same of all properties, but differs in which internal class it uses, which is set via constructor.AbstractEntity::initProperty
does not know what type it needs to create container with, so I though I would do something alongside those lines:however, this a/ does obviously not work, b/ but neither does
setRawValue
(which sets raw value of container, not the value one level above, which I need), c/ would be smelly anyway as the first container would be overwritten immediately.What solutions I though of:
AbstractEntity::initProperty
visibility toprotected
(simple)new $class()
ininitProperty
with call to injected property container factory (clean, but quite involved)new $class()
ininitProperty
with call to protected method that would by default do the same as now (clean, simple)