def greet_a_customer(registry: ServiceRegistry) -> str: # A customer comes in, handle the steps in the greeting # as a container. container = registry.create_container() # First step in the interaction: get a greeter the_greeter: Greeter = container.get(Greeter) # Now do the steps in the interaction greeting = the_greeter() return greeting
def includeme(config): config.add_request_method(find_service_factory) config.add_request_method(find_service) config.add_request_method(get_services, "services", reify=True) config.add_directive("set_service_registry", set_service_registry) config.add_directive("register_service", register_service) config.add_directive("register_service_factory", register_service_factory) config.add_directive("find_service_factory", find_service_factory) config.set_service_registry(ServiceRegistry())
def greet_customer(registry: ServiceRegistry, customer: Customer) -> str: # A customer comes in, handle the steps in the greeting # as a container. container = registry.create_container() # Get a Greeter using the customer as context. Use the Customer when # generating the greeting. greeter: Greeter = container.get(Greeter, context=customer) greeting = greeter(customer) return greeting
def render_path(registry: ServiceRegistry, resource_path: str) -> str: """ Render a resource at a path, to a string """ # Get the root, then the context at the path container1: ServiceContainer = registry.create_container() root: Root = container1.get(IRoot) context: Resource = find_resource(root, resource_path) # Now make a container to process this context container2: ServiceContainer = registry.create_container(context=context) view: View = container2.get(IView) renderer: JinjaRenderer = container2.get(IJinjaRenderer) context_dict = as_dict(view) template_name = view.template markup: Markup = renderer.render(context_dict, template_name=template_name, container=container2) return str(markup)
def setup(settings: Settings) -> ServiceRegistry: # Make the registry registry = ServiceRegistry() # Make the greeter factory, using punctuation from settings punctuation = settings.punctuation # First the default greeter, no context def default_greeter_factory(container) -> Greeter: # Use the dataclass default for greeting return Greeter(punctuation=punctuation) # Register it as a factory using its class for the "key" registry.register_factory(default_greeter_factory, Greeter) # Import the add-on and initialize it from .custom import setup setup(registry, settings) return registry
def setup(registry: ServiceRegistry, settings: Settings): """ Initialize the features in the core application """ # Make and register the Datastore datastore = Datastore() registry.register_singleton(datastore, Datastore) # **** Default Greeter # Make the greeter factory, using punctuation from settings punctuation = settings.punctuation def default_greeter_factory(container) -> Greeter: # Use the dataclass default for greeting return Greeter(punctuation=punctuation) # Register it as a factory using its class for the "key" registry.register_factory(default_greeter_factory, Greeter) # During bootstrap, make some Customers customer1 = Customer(name='Mary') datastore.customers.append(customer1)
def register_view( registry: ServiceRegistry, target: Callable = None, context: Optional[Type] = None, name: Optional[str] = None, ): """ Imperative form of the view decorator """ def view_factory(container: ServiceContainer): injector = Injector(container) view_instance = injector(target) return view_instance if name is None: registry.register_factory( view_factory, View, context=context ) else: registry.register_factory( view_factory, View, context=context, name=name )
def register_dataclass(registry: ServiceRegistry, target, for_=None, context=None): """ Generic injectory factory for dataclasses """ # The common case, for default registrations we can omit # the "for_" as it is the same as the class implementing it if for_ is None: for_ = target if getattr(target, 'wired_factory', None): # This class wants to control its factory, use that one dataclass_factory = target.wired_factory else: # Use a generic dataclass factory def dataclass_factory(c: ServiceContainer): instance = injector_construction(c, target) return instance registry.register_factory(dataclass_factory, for_, context=context)
def app_bootstrap(settings: Settings) -> ServiceRegistry: # Make the registry registry = ServiceRegistry() # Do setup for the core application features setup(registry, settings) # Import the add-on and initialize it from .custom import setup as addon_setup addon_setup(registry, settings) return registry
def app(): # Do this once at startup registry = ServiceRegistry() registry.register_factory(greeter_factory, Greeter) registry.register_factory(Greeting, Greeting) # Do this for every "request" or operation container = registry.create_container() greeting: Greeting = container.get(Greeting) assert 'Hello from Marie' == greeting.greet()
def setup(settings: Settings) -> ServiceRegistry: # Make the registry registry = ServiceRegistry() # Make the greeter factories, using punctuation from settings punctuation = settings.punctuation # First the default greeter, no context def default_greeter_factory(container) -> Greeter: # Use the dataclass default for greeting return Greeter(punctuation=punctuation) # Register it as a factory using its class for the "key" registry.register_factory(default_greeter_factory, Greeter) # Now the French greeter, using context of FrenchCustomer def french_greeter_factory(container) -> Greeter: # Use the dataclass default for greeting return FrenchGreeter(punctuation=punctuation) # Register it as a factory using its class for the "key", but # this time register with a "context" registry.register_factory( french_greeter_factory, Greeter, context=FrenchCustomer ) return registry
class App: def __init__(self): self.registry = ServiceRegistry() scanner = venusian.Scanner(registry=self.registry) scanner.scan(models) def __enter__(self): self.container = self.registry.create_container() return self.container def __exit__(self, exc_type, exc_val, exc_tb): if self.container: del self.container
def register_dataclass(registry: ServiceRegistry, target, for_, context=None): """ Generic injectory factory for dataclasses """ # Note: This function could be a decorator which already knows # the registry, has all the targets, and can do them in one # container that it makes. For example: # from wired.decorators import factory # @factory(for_=Greeter, context=FrenchCustomer) # @datclass # class FrenchGreeter(Greeter): # pass if getattr(target, 'factory', None): # This class wants to control its factory, use that one dataclass_factory = target.factory else: # Use a generic dataclass factory def dataclass_factory(c: ServiceContainer): instance = injector_construction(c, target) return instance registry.register_factory(dataclass_factory, for_, context=context)
def wired_setup(registry: ServiceRegistry): # Wire up the normal parts of wired_components global_setup(registry) # Wire up configuration and root configuration_setup(registry) root_setup(registry) # Get the scanner and look for things container = registry.create_container() scanner: WiredScanner = container.get(IScanner) scanner.scan(components) scanner.scan(views)
def register_component(registry: ServiceRegistry, target: Callable, context: Type[Resource] = IResource): """ Imperative form of the component decorator """ component_name = target.__name__ def component_factory(container: ServiceContainer): def construct_component(**props): """ A partial-partial, used to collect kwargs during calling """ all_args = props.copy() # TODO Would be nice to replace this with DI once wired # supports props. # Only pass resource or view if the dataclass wants it fields = get_type_hints(target) if 'request' in fields: request: Request = container.get(Request) all_args['request'] = request if 'context' in fields: all_args['context'] = container.context if 'view' in fields: view: View = container.get(View) all_args['view'] = view component_instance = target(**all_args) return component_instance return construct_component # Use the name of the class, e.g. Breadcrumb, as the name argument # during registration registry.register_factory(component_factory, IComponent, context=context, name=component_name) # Next, add a zope.interface "subscription" to allow later reading of # all registered components adapter_registry: AdapterRegistry = registry._factories adapter_registry.subscribe([IResource], IComponent, target)
def process_request(registry: ServiceRegistry, url: str) -> str: """ Given URL (customer name), make a Request to handle interaction """ # Make the container that this request gets processed in container = registry.create_container() # Put the url into the container container.register_singleton(url, Url) # Create a View to generate the greeting view = container.get(View) # Generate a response response = view() return response
def render_vdom( registry: ServiceRegistry, vdom: VDOM, context: Optional[Any] = None, resource: Optional[Resource] = None, singletons: Singletons = tuple(), ) -> str: """ Render a VDOM to string with optional context/resource """ container = registry.create_container(context=context) for service, iface in singletons: container.register_singleton(service, iface) if resource is not None: container.register_singleton(resource, Resource) result = render(vdom, container=container) return result
def render_component( registry: ServiceRegistry, component: Component, context: Optional[Any] = None, resource: Optional[Resource] = None, singletons: Singletons = tuple(), ) -> str: """ Render a component to string with optional context/resource """ register_component(registry, component) container = registry.create_container(context=context) for service, iface in singletons: container.register_singleton(service, iface) if resource is not None: container.register_singleton(resource, Resource) vdom = html('<{component} />') result = render(vdom, container=container) return result
def process_request(registry: ServiceRegistry, url_value: str) -> str: """ Given URL (customer name), make a Request to handle interaction """ from .models import Resource, View, Url # Make the container that this request gets processed in container = registry.create_container() # Put the url into the container url = Url(value=url_value) container.register_singleton(url, Url) # Get the context context = container.get(Resource) # Create a View to generate the greeting view = container.get(View, context=context) # Generate a response response = view() return response
def render_template( registry: ServiceRegistry, template: VDOM, context: Optional[Any] = None, resource: Optional[Resource] = None, singletons: Singletons = tuple(), ) -> str: """ Find/render template string with optional context/resource Any needed components must be registered before passing in registry. """ container = registry.create_container(context=context) for service, iface in singletons: container.register_singleton(service, iface) if resource is not None: container.register_singleton(resource, Resource) result = render(template, container=container) return result
def test_component_register_component2( registry: ServiceRegistry, simple_root, ): from wired_components.component import IComponent from wired_components.component.register_component import register_component2 # Register a component @implementer(IComponent) @dataclass class SomeComponent: flag: int register_component2(registry, SomeComponent) # Make a container with an IResource in it container = registry.create_container(context=simple_root) # Now get the component *class* component_class = container.get(IComponent, name='SomeComponent') # Now construct the component instance the correct way, with a prop component_instance: SomeComponent = component_class(flag=44) assert component_instance.flag == 44
def app_bootstrap(settings: Settings) -> ServiceRegistry: # Make the registry registry = ServiceRegistry() # Store the settings in the registry so things later can # get to them. registry.register_singleton(settings, Settings) # Make and register the Datastore singleton datastore = Datastore() registry.register_singleton(datastore, Datastore) # Do setup for the core application features setup(registry, datastore) # Import the add-on and initialize it from .custom import setup as addon_setup addon_setup(registry, datastore) return registry
def registry(): return ServiceRegistry()
def registry(): from wired import ServiceRegistry return ServiceRegistry()
def wired_setup( registry: ServiceRegistry, scanner: Scanner, ): registry.register_factory(resource_factory, Resource) scanner.scan(themester.sphinx)
def test(): registry = ServiceRegistry() enable_autowire(registry) impl00 = object() impl01 = object() impl02 = object() impl03 = object() registry.register_singleton(impl00, Iface00) registry.register_singleton(impl01, name="impl01") registry.register_singleton(impl02, name="r_impl02") registry.register_singleton(impl03, context=Ctxt) registry.register_autowire(Foo, IFoo, namespace=dict(n_impl02="r_impl02", n_impl03=Ctxt())) container = registry.create_container() foo = container.get(IFoo) assert foo.impl00 is impl00 assert foo.impl01 is impl01 assert foo.impl02 is impl02 assert foo.impl03 is impl03
def __init__(self): self.registry = ServiceRegistry() scanner = venusian.Scanner(registry=self.registry) scanner.scan(models)
def __init__(self): self._registry = ServiceRegistry()
def registry(): registry = ServiceRegistry() scanner = venusian.Scanner(registry=registry) scanner.scan(__import__(__name__)) return registry
def wired_setup(registry: ServiceRegistry): registry.register_factory(context_parents, IParents)