=========
Factories
=========


The Factory Class
-----------------

  >>> from zope.interface import Interface
  >>> class IFunction(Interface):
  ...     pass

  >>> class IKlass(Interface):
  ...     pass

  >>> from zope.interface import implements
  >>> class Klass(object):
  ...     implements(IKlass)
  ... 
  ...     def __init__(self, *args, **kw):
  ...         self.args = args
  ...         self.kw = kw

  >>> from zope.component.factory import Factory
  >>> factory = Factory(Klass, 'Klass', 'Klassier')
  >>> factory2 = Factory(lambda x: x, 'Func', 'Function')
  >>> factory3 = Factory(lambda x: x, 'Func', 'Function', (IFunction,))

Calling a Factory
+++++++++++++++++

Here we test whether the factory correctly creates the objects and
including the correct handling of constructor elements.

First we create a factory that creates instanace of the `Klass` class:

  >>> factory = Factory(Klass, 'Klass', 'Klassier')

Now we use the factory to create the instance

  >>> kl = factory(1, 2, foo=3, bar=4)

and make sure that the correct class was used to create the object:

  >>> kl.__class__
  <class 'Klass'>

Since we passed in a couple positional and keyword arguments
  
  >>> kl.args
  (1, 2)
  >>> kl.kw
  {'foo': 3, 'bar': 4}
  
  >>> factory2(3)
  3
  >>> factory3(3)
  3


Title and Description
+++++++++++++++++++++

  >>> factory.title
  'Klass'
  >>> factory.description
  'Klassier'
  >>> factory2.title
  'Func'
  >>> factory2.description
  'Function'
  >>> factory3.title
  'Func'
  >>> factory3.description
  'Function'


Provided Interfaces
+++++++++++++++++++

  >>> implemented = factory.getInterfaces()
  >>> implemented.isOrExtends(IKlass)
  True
  >>> list(implemented)
  [<InterfaceClass __builtin__.IKlass>]
  
  >>> implemented2 = factory2.getInterfaces()
  >>> list(implemented2)
  []
  
  >>> implemented3 = factory3.getInterfaces()
  >>> list(implemented3)
  [<InterfaceClass __builtin__.IFunction>]


The Componant Architecture Factory API
--------------------------------------

  >>> import zope.component
  >>> factory = Factory(Klass, 'Klass', 'Klassier')
  >>> gsm = zope.component.getGlobalSiteManager() 

  >>> from zope.component.interfaces import IFactory
  >>> gsm.provideUtility(IFactory, factory, 'klass')

Creating an Object
++++++++++++++++++

  >>> kl = zope.component.createObject('klass', 1, 2, foo=3, bar=4)
  >>> isinstance(kl, Klass)
  True
  >>> kl.args
  (1, 2)
  >>> kl.kw
  {'foo': 3, 'bar': 4}

Accessing Provided Interfaces
+++++++++++++++++++++++++++++

  >>> implemented = zope.component.getFactoryInterfaces('klass')
  >>> implemented.isOrExtends(IKlass)
  True
  >>> [iface for iface in implemented]
  [<InterfaceClass __builtin__.IKlass>]

List of All Factories
+++++++++++++++++++++

  >>> [(name, fac.__class__) for name, fac in
  ...  zope.component.getFactoriesFor(IKlass)]
  [(u'klass', <class 'zope.component.factory.Factory'>)]

