[PEAK] References between models
Radek Kanovsky
rk at dat.cz
Thu Nov 13 11:14:02 EST 2003
Hi all,
I am not sure how to solve this problem. There is following directory
structure:
mylib/: __init__.py
mylib/contact/: __init__.py model.py storage.py ...
mylib/invoice/: __init__.py model.py storage.py ...
mylib/service/: __init__.py model.py storage.py ...
....
`contact', `invoice', `service', etc. are components that contains
Element definitions (model.py) and corresponding data managers
(storage.py). Every component implements one aspect or problem
and application is simply built (often) by assembling components
together. But it is obvious that invoices must belong to some
subject so there is reference to mylib.contact.model.Contact from
mylib.invoice.model.Invoice:
mylib/invoice/model.py:
class Invoice (model.Element) :
...
class contact (model.Attribute) :
referencedType = mylib.contact.model.Contact
...
And that is exactly what I don't like very much. There are for example
15 components that have reference to mylib.contact.model.Contact. If
there is need for replacing default mylib.contact.model.Contact with
something slightly different, I need to repair 15 Elements in particular
application only for this simple purpose.
I am not sure where to aim my investigation. Elements don't support
properties lookup and have restricted component lookup because they
have no IConfigurationRoot among parents. What I am thinking of now is
something as ElementTemplate with some substitution capabilities.
Not finished yet, just idea:
mylib/invoice/model.py:
class Invoice (model.ElementTemplate) :
...
class contact (model.Attribute) :
referencedType = model.Substitute(
PropertyName("mylib.contact.model.Contact"),
)
mylib/invoice/storage.py:
class InvoiceDM (storage.EntityDM) :
# Find Element or ElementTemplate under this property
_elementName = PropertyName("mylib.invoice.model.Invoice")
# Default for "mylib.invoice.model.Invoice" if not found
_defaultClass = model.Invoice
def defaultClass (self) :
e = self.lookupComponent(
self._elementName,
default=self._defaultClass,
)
if issubclass(e, model.ElementTemplate) :
# Template substitution method has now access
# to the same configured properties as InvoiceDM has
# so it can find "mylib.contact.model.Contact"
# property.
e = <<< make Element class from Template somehow >>>
return e
defaultClass = binding.Make(defaultClass)
my_app.ini:
[mylib.contact]
# I declare that "mylib.contact.model.Contact" property
# is "mylib.contact.model.Contact" class.
#
# This is default only for mylib.contact.storage.ContactDM
# (not for mylib.invoice.model.Invoice) so I must declare
# the property explicitely.
model.Contact = importString("mylib.contact.model:Contact")
# I can replace this default Contact model with other one.
#
# model.Contact = importString("yourlib.kontakt.model:Kontakt")
#
# Of course, there must be also special data manager for the
# Kontakt in application if default ContactDM refuses work
# with Kontakt.
[mylib.invoice]
# This is useless definition. Invoice is not referenced
# from other places and InvoiceDM has default model.Invoice.
model.Invoice = importString("mylib.invoice.model:Invoice")
Is this reasonable? Is there some other solution for such situations?
Regards
Radek Kanovsky
More information about the PEAK
mailing list