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