1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
//! This module contains trait definitions for provided services and interfaces use crate::module::ModuleInterface; use crate::Module; use std::error::Error; /// Like [`Component`]s, providers provide a service by implementing an interface. /// /// Unlike [`Component`], `Provider` represents a temporary service. Examples include a connection /// to a remote service or pooled database connection. Because only providers can have other /// providers as dependencies, services which use these provided services must also be `Provider`s /// (ex. DB repository, service using a DB repository, etc). /// /// See also the [provider getting started guide]. /// /// [`Component`]: trait.Component.html /// [provider getting started guide]: guide/provider/index.html pub trait Provider<M: Module>: 'static { /// The trait/interface which this provider implements type Interface: ?Sized; /// Provides the service, possibly resolving other components/providers /// to do so. fn provide(module: &M) -> Result<Box<Self::Interface>, Box<dyn Error>>; } /// The type signature of [`Provider::provide`]. This is used when overriding a /// provider via [`ModuleBuilder::with_provider_override`] /// /// [`Provider::provide`]: trait.Provider.html#tymethod.provide /// [`ModuleBuilder::with_provider_override`]: struct.ModuleBuilder.html#method.with_provider_override #[cfg(not(feature = "thread_safe"))] pub type ProviderFn<M, I> = Box<dyn (Fn(&M) -> Result<Box<I>, Box<dyn Error>>)>; /// The type signature of [`Provider::provide`]. This is used when overriding a /// provider via [`ModuleBuilder::with_provider_override`] /// /// [`Provider::provide`]: trait.Provider.html#tymethod.provide /// [`ModuleBuilder::with_provider_override`]: struct.ModuleBuilder.html#method.with_provider_override #[cfg(feature = "thread_safe")] pub type ProviderFn<M, I> = Box<dyn (Fn(&M) -> Result<Box<I>, Box<dyn Error>>) + Send + Sync>; /// Indicates that a module contains a provider which implements the interface. pub trait HasProvider<I: ?Sized>: ModuleInterface { /// Create a service using the provider registered with the interface `I`. /// Each call will create a new instance of the service. /// /// # Examples /// ``` /// # use shaku::{module, HasProvider, Provider}; /// # use std::sync::Arc; /// # /// # trait Foo {} /// # /// # #[derive(Provider)] /// # #[shaku(interface = Foo)] /// # struct FooImpl; /// # impl Foo for FooImpl {} /// # /// # module! { /// # TestModule { /// # components = [], /// # providers = [FooImpl] /// # } /// # } /// # /// # fn main() { /// # let module = TestModule::builder().build(); /// # /// let foo: Box<dyn Foo> = module.provide().unwrap(); /// # } /// ``` fn provide(&self) -> Result<Box<I>, Box<dyn Error>>; }