- summary Building a simple web application using dependency injection
- labels Featured
We are going to build a simple web application, which will demonstrate how dependency injection simplifies development and allows to write concise and maintainable code. The application will do nothing but store messages in a fake database, similar to a guest books.
We will use Python 2.6, which has class decorators.
First, let's create a simple WSGI hello-world application. We will extend it gradually, and introduce dependency injection step-by-step.
Now we will create our business logic: a messages database, a message model, and a repository which connects them (in Django it is called a manager).
But we have some requirements. First, the database has to be instantiated only once for the whole application, so that it can store all messages for all requests. Second, a repository has to be instantiated with a database instance. Third, the model uses a repository instance to provide ActiveRecord functionality.
Without dependency injection we would have to create a global variable with the database (or a factory) and then reference it directly in the repository, and reference the repository directly in the model. However, in this case we hard-code all the dependencies and lose testability and flexibility.
Instead, we will use dependency injection.
Now let's add a controller, which will be used by our application to produce output and add messages. The application will use the controller several times in different methods, but we need only one instance per a request. Actually, using a controller here is far-fetched, but we need to demonstrate the request scope somehow.
There is one problem, our database needs a host, a port, etc. to be instantiated (actually, our database doesn't, but any normal database does). We will make a special method, `connect_to_db`, which will get all the required arguments from configuration and return a database instance. To simplify the code let's store the config in a dict.
Now we need to configure dependency injection to use our `connect_to_db` method when injecting the `Database` class, and wrap our application with `WsgiInjectMiddleware` to add support for request scope. This is the only configuration we need for the whole application.
Now you can run `python tutorial.py` (or what ever your file is), and open http://127.0.0.1:8000/ in the browser. Of course, this application is supposed to be run in a single process, not by `mod_python` or `mod_wsgi`, which can use multiple processes.
It is also present in the archive in the Examples folder.
- Copy and run*: