Author: Derick Rethans Date: 2007-04-20 16:53:39 +0200 (Fri, 20 Apr 2007) New Revision: 4907
Log: - Added information about "Dependency Injection" - Fixed broken documentation in example. Modified: docs/guidelines/implementation.txt Modified: docs/guidelines/implementation.txt =================================================================== --- docs/guidelines/implementation.txt 2007-04-20 14:52:23 UTC (rev 4906) +++ docs/guidelines/implementation.txt 2007-04-20 14:53:39 UTC (rev 4907) @@ -536,6 +536,86 @@ Patterns ======== +Dependency Injection +-------------------- + +Some components return objects based on parsed information. This includes the +Mail and DatabaseSchema components. In some situations it's desirable that the +classes of the objects can be modified so that the user of a component can use +his own inherited classes instead. This we call "Dependency Injection". + +The configuration of which class to return has to be done with Options_. +In the option class there needs to be a check if the requested class name +actually inherits the base class that would be used by default, such as in the +following code:: + + function __set( $propertyName, $propertyValue ) + { + $parentClassMap = array( + 'tableClassName' => 'ezcDbSchemaTable', + 'fieldClassName' => 'ezcDbSchemaField', + 'indexClassName' => 'ezcDbSchemaIndex', + 'indexFieldClassName' => 'ezcDbSchemaIndexField', + ); + switch ( $propertyName ) + { + case 'tableClassName': + case 'fieldClassName': + case 'indexClassName': + case 'indexFieldClassName': + if ( !is_string( $propertyValue ) ) + { + throw new ezcBaseValueException( $propertyName, $propertyValue, 'string that contains a class name' ); + } + + // Check if the passed classname actually implements the + // correct parent class. We have to do that with reflection + // here unfortunately + $parentClass = new ReflectionClass( $parentClassMap[$propertyName] ); + $handlerClass = new ReflectionClass( $propertyValue ); + if ( $parentClassMap[$propertyName] !== $propertyValue && !$handlerClass->isSubclassOf( $parentClass ) ) + { + throw new ezcBaseInvalidParentClassException( $parentClassMap[$propertyName], $propertyValue ); + } + + $this->properties[$propertyName] = $propertyValue; + break; + + + ... other options ... + } + } + +In case there is only one class name to modify, this can of course be +simplified to something like the following:: + + public function __set( $propertyName, $propertyValue ) + { + switch ( $propertyName ) + { + case 'mailClass': + if ( !is_string( $propertyValue ) ) + { + throw new ezcBaseValueException( $propertyName, $propertyValue, 'string that contains a class name' ); + } + + // Check if the passed classname actually implements the + // correct parent class. We have to do that with reflection + // here unfortunately + $parentClass = new ReflectionClass( 'ezcMail' ); + $handlerClass = new ReflectionClass( $propertyValue ); + if ( 'ezcMail' !== $propertyValue && !$handlerClass->isSubclassOf( $parentClass ) ) + { + throw new ezcBaseInvalidParentClassException( 'ezcMail', $propertyValue ); + } + $this->properties[$propertyName] = $propertyValue; + break; + + ... other options ... + } + } + + Singletons ---------- @@ -761,7 +841,7 @@ /** * ... - * @param ezcMailTransportOptions $options + * @param ezcFooBarOptions $options */ public function __construct( ezcFooBarOptions $options = null ) { -- svn-components mailing list svn-components@lists.ez.no http://lists.ez.no/mailman/listinfo/svn-components