use crate::{ServiceDescriptor, ServiceLifetime};
pub trait Injectable: Sized {
fn inject(lifetime: ServiceLifetime) -> ServiceDescriptor;
fn singleton() -> ServiceDescriptor {
Self::inject(ServiceLifetime::Singleton)
}
fn scoped() -> ServiceDescriptor {
Self::inject(ServiceLifetime::Scoped)
}
fn transient() -> ServiceDescriptor {
Self::inject(ServiceLifetime::Transient)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::*;
trait TestService {}
trait OtherTestService {}
#[derive(Default)]
struct TestServiceImpl {}
struct OtherTestServiceImpl {
_service: ServiceRef<dyn TestService>,
}
impl TestService for TestServiceImpl {}
impl Injectable for TestServiceImpl {
fn inject(lifetime: ServiceLifetime) -> ServiceDescriptor {
ServiceDescriptorBuilder::<dyn TestService, Self>::new(lifetime, Type::of::<Self>())
.from(|_| ServiceRef::new(Self::default()))
}
}
impl OtherTestServiceImpl {
fn new(service: ServiceRef<dyn TestService>) -> Self {
Self { _service: service }
}
}
impl Injectable for OtherTestServiceImpl {
fn inject(lifetime: ServiceLifetime) -> ServiceDescriptor {
ServiceDescriptorBuilder::<dyn OtherTestService, Self>::new(
lifetime,
Type::of::<Self>(),
)
.from(|sp| ServiceRef::new(Self::new(sp.get_required::<dyn TestService>())))
}
}
impl OtherTestService for OtherTestServiceImpl {}
#[test]
fn inject_should_invoke_constructor_injection() {
let services = ServiceCollection::new()
.add(TestServiceImpl::singleton())
.add(OtherTestServiceImpl::transient())
.build_provider();
let service = services.get::<dyn OtherTestService>();
assert!(service.is_some());
}
}