WIP: dev into master #184

Draft
edraft wants to merge 121 commits from dev into master
14 changed files with 46 additions and 57 deletions
Showing only changes of commit cf4aa8291f - Show all commits

View File

@@ -1,11 +1,14 @@
from cpl import auth from cpl import auth
from cpl.application.abc.startup_abc import StartupABC from cpl.application.abc.startup_abc import StartupABC
from cpl.auth import permission from cpl.auth import permission
from cpl.auth.auth_module import AuthModule
from cpl.auth.permission.permission_module import PermissionsModule
from cpl.core.configuration import Configuration from cpl.core.configuration import Configuration
from cpl.core.environment import Environment from cpl.core.environment import Environment
from cpl.core.log import Logger, LoggerABC from cpl.core.log import Logger, LoggerABC
from cpl.database import mysql from cpl.database import mysql
from cpl.database.abc.data_access_object_abc import DataAccessObjectABC from cpl.database.abc.data_access_object_abc import DataAccessObjectABC
from cpl.database.mysql.mysql_module import MySQLModule
from cpl.dependency import ServiceCollection from cpl.dependency import ServiceCollection
from model.city_dao import CityDao from model.city_dao import CityDao
from model.user_dao import UserDao from model.user_dao import UserDao
@@ -21,9 +24,9 @@ class Startup(StartupABC):
@staticmethod @staticmethod
async def configure_services(services: ServiceCollection): async def configure_services(services: ServiceCollection):
services.add_module(mysql) services.add_module(MySQLModule)
services.add_module(auth) services.add_module(AuthModule)
services.add_module(permission) services.add_module(PermissionsModule)
services.add_transient(DataAccessObjectABC, UserDao) services.add_transient(DataAccessObjectABC, UserDao)
services.add_transient(DataAccessObjectABC, CityDao) services.add_transient(DataAccessObjectABC, CityDao)

View File

@@ -1,11 +1,10 @@
from cpl.application.abc import ApplicationABC from cpl.application.abc import ApplicationABC
from cpl.core.console.console import Console from cpl.core.console.console import Console
from cpl.dependency import ServiceProvider from cpl.dependency import ServiceProvider
from di.static_test import StaticTest from test_abc import TestABC
from di.test_abc import TestABC from test_service import TestService
from di.test_service import TestService from di_tester_service import DITesterService
from di.di_tester_service import DITesterService from tester import Tester
from di.tester import Tester
class Application(ApplicationABC): class Application(ApplicationABC):
@@ -39,7 +38,8 @@ class Application(ApplicationABC):
Console.write_line("Global") Console.write_line("Global")
self._part_of_scoped() self._part_of_scoped()
StaticTest.test() #from static_test import StaticTest
#StaticTest.test()
self._services.get_service(Tester) self._services.get_service(Tester)
Console.write_line(self._services.get_services(TestABC)) Console.write_line(self._services.get_services(TestABC))

View File

@@ -1,5 +1,5 @@
from cpl.core.console.console import Console from cpl.core.console.console import Console
from di.test_service import TestService from test_service import TestService
class DITesterService: class DITesterService:

View File

@@ -1,7 +1,7 @@
from cpl.application import ApplicationBuilder from cpl.application import ApplicationBuilder
from di.application import Application from application import Application
from di.startup import Startup from startup import Startup
def main(): def main():

View File

@@ -1,11 +1,11 @@
from cpl.application.abc import StartupABC from cpl.application.abc import StartupABC
from cpl.dependency import ServiceProvider, ServiceCollection from cpl.dependency import ServiceProvider, ServiceCollection
from di.di_tester_service import DITesterService from di_tester_service import DITesterService
from di.test1_service import Test1Service from test1_service import Test1Service
from di.test2_service import Test2Service from test2_service import Test2Service
from di.test_abc import TestABC from test_abc import TestABC
from di.test_service import TestService from test_service import TestService
from di.tester import Tester from tester import Tester
class Startup(StartupABC): class Startup(StartupABC):

View File

@@ -1,6 +1,6 @@
from cpl.dependency import ServiceProvider, ServiceProvider from cpl.dependency import ServiceProvider, ServiceProvider
from cpl.dependency.inject import inject from cpl.dependency.inject import inject
from di.test_service import TestService from test_service import TestService
class StaticTest: class StaticTest:

View File

@@ -1,7 +1,7 @@
import string import string
from cpl.core.console.console import Console from cpl.core.console.console import Console
from cpl.core.utils.string import String from cpl.core.utils.string import String
from di.test_abc import TestABC from test_abc import TestABC
class Test1Service(TestABC): class Test1Service(TestABC):

View File

@@ -1,7 +1,7 @@
import string import string
from cpl.core.console.console import Console from cpl.core.console.console import Console
from cpl.core.utils.string import String from cpl.core.utils.string import String
from di.test_abc import TestABC from test_abc import TestABC
class Test2Service(TestABC): class Test2Service(TestABC):

View File

@@ -1,8 +1,7 @@
from cpl.core.console.console import Console from cpl.core.console.console import Console
from di.test_abc import TestABC from test_abc import TestABC
class Tester: class Tester:
def __init__(self, t1: TestABC, t2: TestABC, t3: list[TestABC]): def __init__(self, t1: TestABC, t2: TestABC, t3: TestABC, t: list[TestABC]):
Console.write_line("Tester:") Console.write_line("Tester:", t, t1, t2, t3)
Console.write_line(t1, t2, t3)

View File

@@ -48,9 +48,9 @@ def t_benchmark(data: list):
def main(): def main():
N = 10_000_000 N = 1_000_000
data = list(range(N)) data = list(range(N))
#t_benchmark(data) t_benchmark(data)
Console.write_line() Console.write_line()
_default() _default()

View File

@@ -83,6 +83,7 @@ class ApplicationBuilder(Generic[TApp]):
for extension in self._app_extensions: for extension in self._app_extensions:
Host.run(extension.run, self.service_provider) Host.run(extension.run, self.service_provider)
use_root_provider(self._services.build())
app = self._app(self.service_provider) app = self._app(self.service_provider)
self.validate_app_required_modules(app) self.validate_app_required_modules(app)
return app return app

View File

@@ -1,8 +1,8 @@
from cpl.auth.auth_module import AuthModule
from cpl.auth.permission.permission_seeder import PermissionSeeder from cpl.auth.permission.permission_seeder import PermissionSeeder
from cpl.auth.permission.permissions import Permissions from cpl.auth.permission.permissions import Permissions
from cpl.auth.permission.permissions_registry import PermissionsRegistry from cpl.auth.permission.permissions_registry import PermissionsRegistry
from cpl.database.abc.data_seeder_abc import DataSeederABC from cpl.database.abc.data_seeder_abc import DataSeederABC
from cpl.database.model.server_type import ServerType, ServerTypes
from cpl.dependency.module import Module, TModule from cpl.dependency.module import Module, TModule
from cpl.dependency.service_collection import ServiceCollection from cpl.dependency.service_collection import ServiceCollection
@@ -12,21 +12,7 @@ class PermissionsModule(Module):
def dependencies() -> list[TModule]: def dependencies() -> list[TModule]:
from cpl.database.database_module import DatabaseModule from cpl.database.database_module import DatabaseModule
r = [DatabaseModule] return [DatabaseModule, AuthModule]
match ServerType.server_type:
case ServerTypes.POSTGRES:
from cpl.database.postgres.postgres_module import PostgresModule
r.append(PostgresModule)
case ServerTypes.MYSQL:
from cpl.database.mysql.mysql_module import MySQLModule
r.append(MySQLModule)
case _:
raise Exception(f"Unsupported database type: {ServerType.server_type}")
return r
@staticmethod @staticmethod
def register(collection: ServiceCollection): def register(collection: ServiceCollection):

View File

@@ -2,7 +2,7 @@ import contextvars
from contextlib import contextmanager from contextlib import contextmanager
_current_provider = contextvars.ContextVar("current_provider") _current_provider = contextvars.ContextVar("current_provider", default=None)
def use_root_provider(provider: "ServiceProvider"): def use_root_provider(provider: "ServiceProvider"):

View File

@@ -23,6 +23,9 @@ class ServiceProvider:
type_args = list(typing.get_args(service_type)) type_args = list(typing.get_args(service_type))
for descriptor in self._service_descriptors: for descriptor in self._service_descriptors:
if typing.get_origin(service_type) is None and (descriptor.service_type == service_type or issubclass(descriptor.base_type, service_type)):
return descriptor
descriptor_base_type = typing.get_origin(descriptor.base_type) or descriptor.base_type descriptor_base_type = typing.get_origin(descriptor.base_type) or descriptor.base_type
descriptor_type_args = list(typing.get_args(descriptor.base_type)) descriptor_type_args = list(typing.get_args(descriptor.base_type))
@@ -48,7 +51,7 @@ class ServiceProvider:
if descriptor.implementation is not None: if descriptor.implementation is not None:
return descriptor.implementation return descriptor.implementation
implementation = self._build_service(descriptor.service_type, origin_service_type=origin_service_type) implementation = self._build_service(descriptor, origin_service_type=origin_service_type)
if descriptor.lifetime in (ServiceLifetimeEnum.singleton, ServiceLifetimeEnum.scoped): if descriptor.lifetime in (ServiceLifetimeEnum.singleton, ServiceLifetimeEnum.scoped):
descriptor.implementation = implementation descriptor.implementation = implementation
@@ -63,7 +66,7 @@ class ServiceProvider:
continue continue
implementation = self._build_service( implementation = self._build_service(
descriptor.service_type, *args, origin_service_type=service_type, **kwargs descriptor, *args, origin_service_type=service_type, **kwargs
) )
if descriptor.lifetime in (ServiceLifetimeEnum.singleton, ServiceLifetimeEnum.scoped): if descriptor.lifetime in (ServiceLifetimeEnum.singleton, ServiceLifetimeEnum.scoped):
descriptor.implementation = implementation descriptor.implementation = implementation
@@ -78,7 +81,7 @@ class ServiceProvider:
parameter = param[1] parameter = param[1]
if parameter.name != "self" and parameter.annotation != Parameter.empty: if parameter.name != "self" and parameter.annotation != Parameter.empty:
if typing.get_origin(parameter.annotation) == list: if typing.get_origin(parameter.annotation) == list:
params.append(self._get_services(typing.get_args(parameter.annotation)[0], origin_service_type)) params.append(self._get_services(typing.get_args(parameter.annotation)[0], service_type=origin_service_type))
elif parameter.annotation == Source: elif parameter.annotation == Source:
params.append(origin_service_type.__name__) params.append(origin_service_type.__name__)
@@ -101,17 +104,14 @@ class ServiceProvider:
return params return params
def _build_service(self, service_type: type, *args, origin_service_type: type = None, **kwargs) -> object: def _build_service(self, descriptor: ServiceDescriptor, *args, origin_service_type: type = None, **kwargs) -> object:
if origin_service_type is None:
origin_service_type = service_type
for descriptor in self._service_descriptors:
if descriptor.service_type == service_type or issubclass(descriptor.service_type, service_type):
if descriptor.implementation is not None: if descriptor.implementation is not None:
service_type = type(descriptor.implementation) service_type = type(descriptor.implementation)
else: else:
service_type = descriptor.service_type service_type = descriptor.service_type
break
if origin_service_type is None:
origin_service_type = service_type
sig = signature(service_type.__init__) sig = signature(service_type.__init__)
params = self._build_by_signature(sig, origin_service_type) params = self._build_by_signature(sig, origin_service_type)
@@ -142,7 +142,7 @@ class ServiceProvider:
if result.implementation is not None: if result.implementation is not None:
return result.implementation return result.implementation
implementation = self._build_service(service_type, *args, **kwargs) implementation = self._build_service(result, *args, **kwargs)
if result.lifetime == ServiceLifetimeEnum.singleton: if result.lifetime == ServiceLifetimeEnum.singleton:
result.implementation = implementation result.implementation = implementation