Add catalog-providing-callbacks exaple and some tests for it

This commit is contained in:
Roman Mogilatov 2016-03-09 10:25:17 +02:00
parent ad27f44b67
commit 92df7338ca
2 changed files with 187 additions and 0 deletions

View File

@ -0,0 +1,113 @@
"""Concept example of `Dependency Injector`."""
import sqlite3
from dependency_injector import catalogs
from dependency_injector import providers
from dependency_injector import injections
class UsersService(object):
"""Users service, that has dependency on database."""
def __init__(self, db):
"""Initializer."""
self.db = db
class AuthService(object):
"""Auth service, that has dependencies on users service and database."""
def __init__(self, db, users_service):
"""Initializer."""
self.db = db
self.users_service = users_service
class Services(catalogs.DeclarativeCatalog):
"""Catalog of service providers."""
@providers.Singleton
def database():
"""Provide database connection.
:rtype: providers.Provider -> sqlite3.Connection
"""
return sqlite3.connect(':memory:')
@providers.Factory
@injections.inject(db=database)
def users(**kwargs):
"""Provide users service.
:rtype: providers.Provider -> UsersService
"""
return UsersService(**kwargs)
@providers.Factory
@injections.inject(db=database)
@injections.inject(users_service=users)
def auth(**kwargs):
"""Provide users service.
:rtype: providers.Provider -> AuthService
"""
return AuthService(**kwargs)
# Retrieving catalog providers:
users_service = Services.users()
auth_service = Services.auth()
# Making some asserts:
assert users_service.db is auth_service.db is Services.database()
assert isinstance(auth_service.users_service, UsersService)
assert users_service is not Services.users()
assert auth_service is not Services.auth()
# Making some "inline" injections:
@injections.inject(users_service=Services.users)
@injections.inject(auth_service=Services.auth)
@injections.inject(database=Services.database)
def example(users_service, auth_service, database):
"""Example callback."""
assert users_service.db is auth_service.db
assert auth_service.db is database
assert database is Services.database()
# Making a call of decorated callback:
example()
# Overriding auth service provider and making some asserts:
class ExtendedAuthService(AuthService):
"""Extended version of auth service."""
def __init__(self, db, users_service, ttl):
"""Initializer."""
self.ttl = ttl
super(ExtendedAuthService, self).__init__(db=db,
users_service=users_service)
class OverriddenServices(Services):
"""Catalog of service providers."""
@providers.override(Services.auth)
@providers.Factory
@injections.inject(db=Services.database)
@injections.inject(users_service=Services.users)
@injections.inject(ttl=3600)
def auth(**kwargs):
"""Provide users service.
:rtype: providers.Provider -> AuthService
"""
return ExtendedAuthService(**kwargs)
auth_service = Services.auth()
assert isinstance(auth_service, ExtendedAuthService)

View File

@ -4,6 +4,7 @@ import unittest2 as unittest
from dependency_injector import catalogs
from dependency_injector import providers
from dependency_injector import injections
from dependency_injector import errors
@ -670,3 +671,76 @@ class CatalogModuleBackwardCompatibility(unittest.TestCase):
from dependency_injector import catalogs
self.assertIs(catalog, catalogs)
class TestCatalogWithProvidingCallbacks(unittest.TestCase):
"""Catalog with providing callback tests."""
def test_concept(self):
"""Test concept."""
class UsersService(object):
"""Users service, that has dependency on database."""
class AuthService(object):
"""Auth service, that has dependencies on users service."""
def __init__(self, users_service):
"""Initializer."""
self.users_service = users_service
class Services(catalogs.DeclarativeCatalog):
"""Catalog of service providers."""
@providers.Factory
def users():
"""Provide users service.
:rtype: providers.Provider -> UsersService
"""
return UsersService()
@providers.Factory
@injections.inject(users_service=users)
def auth(**kwargs):
"""Provide users service.
:rtype: providers.Provider -> AuthService
"""
return AuthService(**kwargs)
# Retrieving catalog providers:
users_service = Services.users()
auth_service = Services.auth()
# Making some asserts:
self.assertIsInstance(auth_service.users_service, UsersService)
self.assertIsNot(users_service, Services.users())
self.assertIsNot(auth_service, Services.auth())
# Overriding auth service provider and making some asserts:
class ExtendedAuthService(AuthService):
"""Extended version of auth service."""
def __init__(self, users_service, ttl):
"""Initializer."""
self.ttl = ttl
super(ExtendedAuthService, self).__init__(
users_service=users_service)
class OverriddenServices(Services):
"""Catalog of service providers."""
@providers.override(Services.auth)
@providers.Factory
@injections.inject(users_service=Services.users)
@injections.inject(ttl=3600)
def auth(**kwargs):
"""Provide users service.
:rtype: providers.Provider -> AuthService
"""
return ExtendedAuthService(**kwargs)
auth_service = Services.auth()
self.assertIsInstance(auth_service, ExtendedAuthService)