[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