Skip to content

Commit 611bfd3

Browse files
author
Dariusz Suchojad
committed
Adding new ReST files. Added new XMLConfig docs.
1 parent 90fa4b2 commit 611bfd3

10 files changed

+914
-60
lines changed
95 KB
Loading

docs/sphinx/source/objects-more.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
More on IoC
2+
===========
3+
4+
Object Factories
5+
----------------
6+
7+
Testable Code
8+
-------------
9+
10+
Mixing Configuration Modes
11+
--------------------------
12+
13+
14+
Querying and modifying the ApplicationContext in runtime
15+
--------------------------------------------------------
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Other configuration formats
2+
===========================
3+
4+
.. _objects-other-formats-pycontainerconfig:
5+
6+
PyContainerConfig - Spring Python's original XML format
7+
-------------------------------------------------------
8+
9+
.. _objects-other-formats-springjavaconfig:
10+
11+
SpringJavaConfig
12+
----------------
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
PythonConfig and @Object - decorator-driven configuration
2+
=========================================================
3+
4+
By defining a class that extends *PythonConfig* and using the *@Object* decorator,
5+
you can wire your application using pure Python code.::
6+
7+
from springpython.config import PythonConfig
8+
from springpython.config import Object
9+
from springpython.context import scope
10+
11+
class MovieBasedApplicationContext(PythonConfig):
12+
def __init__(self):
13+
super(MovieBasedApplicationContext, self).__init__()
14+
15+
@Object(scope.PROTOTYPE)
16+
def MovieLister(self):
17+
lister = MovieLister()
18+
lister.finder = self.MovieFinder()
19+
lister.description = self.SingletonString()
20+
self.logger.debug("Description = %s" % lister.description)
21+
return lister
22+
23+
@Object(scope.SINGLETON)
24+
def MovieFinder(self):
25+
return ColonMovieFinder(filename="support/movies1.txt")
26+
27+
@Object(lazy_init=True) # scope.SINGLETON is the default
28+
def SingletonString(self):
29+
return StringHolder("There should only be one copy of this string")
30+
31+
def NotExposed(self):
32+
pass
33+
34+
As part of this example, the method NotExposed is also shown. This indicates
35+
that using *get_object* won't fetch that method, since it isn't considered an object.
36+
37+
By using pure Python, you don't have to deal with any XML. If you look closely,
38+
you will notice that the container code below is only different in the line
39+
actually creating the container. Everything else is the same as was in the
40+
:doc:`XMLConfig <objects-xmlconfig>` & :doc:`YamlConfig <objects-yamlconfig>` examples.::
41+
42+
from springpython.context import ApplicationContext
43+
44+
container = ApplicationContext(MovieBasedApplicationContext())
45+
service = container.get_object("MovieLister")
46+
47+
Object definition inheritance
48+
-----------------------------
49+
50+
PythonConfig's support for abstract objects is different to that of XMLConfig
51+
or YamlConfig. With PythonConfig, the children object do not automatically
52+
inherit nor override the parents' properties, they in fact receive the values
53+
returned by their parents and it's up to them to decide, using Python code,
54+
whether to use or to discard the values received.
55+
56+
A child object must have as many optional arguments as there are expected
57+
to be returned by its parent.
58+
59+
Observe that in the following example the child definitions must define
60+
an optional 'req' argument; in runtime they will be passed its value basing
61+
on what their parent object will return. Note also that request is of
62+
PROTOTYPE scope, if it were a SINGLETON then both get_customer_id_request
63+
and get_customer_profile_request would receive the very same Request
64+
instance which, in other circumstances, could be a desirable effect
65+
but not in the example.::
66+
67+
# stdlib
68+
import uuid4
69+
70+
# .. skip Spring Python imports
71+
72+
class Request(object):
73+
def __init__(self, nonce=None, user=None, password=None):
74+
self.nonce = nonce
75+
self.user = user
76+
self.password = password
77+
78+
def __str__(self):
79+
return "<id=%s %s %s %s>" % (hex(id(self)), self.nonce, self.user, self.password)
80+
81+
class TestAbstractContext(PythonConfig):
82+
83+
@Object(scope.PROTOTYPE, abstract=True)
84+
def request(self):
85+
return Request()
86+
87+
@Object(parent="request")
88+
def request_dev(self, req=None):
89+
req.user = "dev-user"
90+
req.password = "dev-password"
91+
92+
return req
93+
94+
@Object(parent="request")
95+
def request_test(self, req=None):
96+
req.user = "test-user"
97+
req.password = "test-password"
98+
99+
return req
100+
101+
@Object(parent="request_dev")
102+
def get_customer_id_request(self, req=None):
103+
req.nonce = uuid4().hex
104+
105+
return req
106+
107+
@Object(parent="request_test")
108+
def get_customer_profile_request(self, req=None):
109+
req.nonce = uuid4().hex
110+
111+
return req
112+
113+
Same as with the other configuration modes, if you need to get an abstract
114+
object from a container, use the .get_object's ignore_abstract parameter,
115+
otherwise springpython.container.AbstractObjectException will be raised::
116+
117+
# .. skip creating the context
118+
119+
# No exception will be raised, even though 'request' is an abstract object
120+
request = ctx.get_object("request", ignore_abstract=True)
121+
122+
# Will show the object
123+
print request
124+
125+
# Will raise AbstractObjectException
126+
request = ctx.get_object("request")

0 commit comments

Comments
 (0)