pub struct IocContainer { /* private fields */ }
Expand description
Modern IoC container with proper dependency injection
Implementations§
Source§impl IocContainer
impl IocContainer
Sourcepub fn from_bindings(bindings: ServiceBindings) -> Self
pub fn from_bindings(bindings: ServiceBindings) -> Self
Create IoC container from existing bindings
Sourcepub fn build(&mut self) -> Result<(), CoreError>
pub fn build(&mut self) -> Result<(), CoreError>
Build the container and prepare for service resolution
Sourcepub async fn initialize_async(&mut self) -> Result<(), CoreError>
pub async fn initialize_async(&mut self) -> Result<(), CoreError>
Initialize all async services
Sourcepub async fn initialize_async_with_timeout(
&mut self,
timeout: Duration,
) -> Result<(), CoreError>
pub async fn initialize_async_with_timeout( &mut self, timeout: Duration, ) -> Result<(), CoreError>
Initialize all async services with timeout
Sourcepub fn create_scope(&self) -> Result<ScopeId, CoreError>
pub fn create_scope(&self) -> Result<ScopeId, CoreError>
Create a new service scope
Sourcepub fn create_child_scope(
&self,
parent_scope_id: &ScopeId,
) -> Result<ScopeId, CoreError>
pub fn create_child_scope( &self, parent_scope_id: &ScopeId, ) -> Result<ScopeId, CoreError>
Create a child scope from an existing scope
Sourcepub async fn dispose_scope(&self, scope_id: &ScopeId) -> Result<(), CoreError>
pub async fn dispose_scope(&self, scope_id: &ScopeId) -> Result<(), CoreError>
Dispose of a scope and all its services
Sourcepub async fn dispose_all(&mut self) -> Result<(), CoreError>
pub async fn dispose_all(&mut self) -> Result<(), CoreError>
Dispose all scoped services and lifecycle managed services
Sourcepub fn lifecycle_manager(&self) -> &ServiceLifecycleManager
pub fn lifecycle_manager(&self) -> &ServiceLifecycleManager
Get a reference to the lifecycle manager
Sourcepub fn lifecycle_manager_mut(&mut self) -> &mut ServiceLifecycleManager
pub fn lifecycle_manager_mut(&mut self) -> &mut ServiceLifecycleManager
Get a mutable reference to the lifecycle manager
Sourcepub fn resolve<T: Send + Sync + 'static>(&self) -> Result<Arc<T>, CoreError>
pub fn resolve<T: Send + Sync + 'static>(&self) -> Result<Arc<T>, CoreError>
Resolve a service by type
Sourcepub fn resolve_scoped<T: Send + Sync + 'static>(
&self,
scope_id: &ScopeId,
) -> Result<Arc<T>, CoreError>
pub fn resolve_scoped<T: Send + Sync + 'static>( &self, scope_id: &ScopeId, ) -> Result<Arc<T>, CoreError>
Resolve a scoped service by type
Sourcepub fn resolve_named<T: Send + Sync + 'static>(
&self,
name: &str,
) -> Result<Arc<T>, CoreError>
pub fn resolve_named<T: Send + Sync + 'static>( &self, name: &str, ) -> Result<Arc<T>, CoreError>
Resolve a named service
Sourcepub fn try_resolve<T: Send + Sync + 'static>(&self) -> Option<Arc<T>>
pub fn try_resolve<T: Send + Sync + 'static>(&self) -> Option<Arc<T>>
Try to resolve a service, returning None if not found
Sourcepub fn try_resolve_named<T: Send + Sync + 'static>(
&self,
name: &str,
) -> Option<Arc<T>>
pub fn try_resolve_named<T: Send + Sync + 'static>( &self, name: &str, ) -> Option<Arc<T>>
Try to resolve a named service, returning None if not found
Sourcepub fn resolve_injectable<T: Injectable>(&self) -> Result<Arc<T>, CoreError>
pub fn resolve_injectable<T: Injectable>(&self) -> Result<Arc<T>, CoreError>
Resolve a service using the Injectable trait (auto-wiring)
Sourcepub fn resolve_trait<T: ?Sized + Send + Sync + 'static>(
&self,
) -> Result<Arc<T>, CoreError>
pub fn resolve_trait<T: ?Sized + Send + Sync + 'static>( &self, ) -> Result<Arc<T>, CoreError>
Resolve a trait object by downcasting from a concrete implementation
Sourcepub fn bind_token<Token, Impl>(&mut self) -> Result<&mut Self, CoreError>
pub fn bind_token<Token, Impl>(&mut self) -> Result<&mut Self, CoreError>
Bind a service token to a concrete implementation with transient lifetime
This creates a mapping from a service token to a concrete implementation, enabling semantic dependency resolution through tokens.
§Example
use elif_core::container::{IocContainer, ServiceToken};
// Define service trait and token
trait EmailService: Send + Sync {}
struct EmailToken;
impl ServiceToken for EmailToken {
type Service = dyn EmailService;
}
// Implementation
#[derive(Default)]
struct SmtpService;
impl EmailService for SmtpService {}
// Bind token to implementation
let mut container = IocContainer::new();
container.bind_token::<EmailToken, SmtpService>()?;
Sourcepub fn bind_token_singleton<Token, Impl>(
&mut self,
) -> Result<&mut Self, CoreError>
pub fn bind_token_singleton<Token, Impl>( &mut self, ) -> Result<&mut Self, CoreError>
Bind a service token to a concrete implementation as a singleton
Sourcepub fn bind_token_scoped<Token, Impl>(&mut self) -> Result<&mut Self, CoreError>
pub fn bind_token_scoped<Token, Impl>(&mut self) -> Result<&mut Self, CoreError>
Bind a service token to a concrete implementation as a scoped service
Sourcepub fn bind_token_with_lifetime<Token, Impl>(
&mut self,
lifetime: ServiceScope,
) -> Result<&mut Self, CoreError>
pub fn bind_token_with_lifetime<Token, Impl>( &mut self, lifetime: ServiceScope, ) -> Result<&mut Self, CoreError>
Bind a service token to a concrete implementation with a specific lifetime
Sourcepub fn bind_token_named<Token, Impl>(
&mut self,
name: impl Into<String>,
) -> Result<&mut Self, CoreError>
pub fn bind_token_named<Token, Impl>( &mut self, name: impl Into<String>, ) -> Result<&mut Self, CoreError>
Bind a named service token to a concrete implementation
Sourcepub fn resolve_by_token<Token>(&self) -> Result<Arc<Token::Service>, CoreError>where
Token: ServiceToken,
Token::Service: 'static,
pub fn resolve_by_token<Token>(&self) -> Result<Arc<Token::Service>, CoreError>where
Token: ServiceToken,
Token::Service: 'static,
Resolve a service by its token type
This enables semantic dependency resolution where services are identified by tokens rather than concrete types, enabling true dependency inversion.
§Example
use std::sync::Arc;
use elif_core::container::{IocContainer, ServiceToken};
// Define service trait and token
trait EmailService: Send + Sync {
fn send(&self, to: &str, subject: &str, body: &str) -> Result<(), String>;
}
struct EmailToken;
impl ServiceToken for EmailToken {
type Service = dyn EmailService;
}
// Implementation
#[derive(Default)]
struct SmtpService;
impl EmailService for SmtpService {
fn send(&self, _to: &str, _subject: &str, _body: &str) -> Result<(), String> {
Ok(()) // Mock implementation
}
}
// Setup and resolve
let mut container = IocContainer::new();
container.bind_token::<EmailToken, SmtpService>()?;
container.build()?;
// Note: Trait object resolution is not yet fully implemented
// This will be available in a future version:
// let service: Arc<dyn EmailService> = container.resolve_by_token::<EmailToken>()?;
// service.send("user@example.com", "Welcome", "Hello world!")?;
Sourcepub fn resolve_by_token_named<Token>(
&self,
name: &str,
) -> Result<Arc<Token::Service>, CoreError>where
Token: ServiceToken,
Token::Service: 'static,
pub fn resolve_by_token_named<Token>(
&self,
name: &str,
) -> Result<Arc<Token::Service>, CoreError>where
Token: ServiceToken,
Token::Service: 'static,
Resolve a named service by its token type
Sourcepub fn try_resolve_by_token<Token>(&self) -> Option<Arc<Token::Service>>where
Token: ServiceToken,
Token::Service: 'static,
pub fn try_resolve_by_token<Token>(&self) -> Option<Arc<Token::Service>>where
Token: ServiceToken,
Token::Service: 'static,
Try to resolve a service by its token type, returning None if not found
Sourcepub fn try_resolve_by_token_named<Token>(
&self,
name: &str,
) -> Option<Arc<Token::Service>>where
Token: ServiceToken,
Token::Service: 'static,
pub fn try_resolve_by_token_named<Token>(
&self,
name: &str,
) -> Option<Arc<Token::Service>>where
Token: ServiceToken,
Token::Service: 'static,
Try to resolve a named service by its token type, returning None if not found
Sourcepub fn resolve_by_token_scoped<Token>(
&self,
scope_id: &ScopeId,
) -> Result<Arc<Token::Service>, CoreError>where
Token: ServiceToken,
Token::Service: 'static,
pub fn resolve_by_token_scoped<Token>(
&self,
scope_id: &ScopeId,
) -> Result<Arc<Token::Service>, CoreError>where
Token: ServiceToken,
Token::Service: 'static,
Resolve a scoped service by its token type
This resolves services within a specific scope, maintaining the lifecycle and cleanup patterns expected by the existing scope management system.
Sourcepub fn resolve_by_token_named_scoped<Token>(
&self,
name: &str,
scope_id: &ScopeId,
) -> Result<Arc<Token::Service>, CoreError>where
Token: ServiceToken,
Token::Service: 'static,
pub fn resolve_by_token_named_scoped<Token>(
&self,
name: &str,
scope_id: &ScopeId,
) -> Result<Arc<Token::Service>, CoreError>where
Token: ServiceToken,
Token::Service: 'static,
Resolve a named scoped service by its token type
Sourcepub fn try_resolve_by_token_scoped<Token>(
&self,
scope_id: &ScopeId,
) -> Option<Arc<Token::Service>>where
Token: ServiceToken,
Token::Service: 'static,
pub fn try_resolve_by_token_scoped<Token>(
&self,
scope_id: &ScopeId,
) -> Option<Arc<Token::Service>>where
Token: ServiceToken,
Token::Service: 'static,
Try to resolve a scoped service by its token type, returning None if not found
Sourcepub fn try_resolve_by_token_named_scoped<Token>(
&self,
name: &str,
scope_id: &ScopeId,
) -> Option<Arc<Token::Service>>where
Token: ServiceToken,
Token::Service: 'static,
pub fn try_resolve_by_token_named_scoped<Token>(
&self,
name: &str,
scope_id: &ScopeId,
) -> Option<Arc<Token::Service>>where
Token: ServiceToken,
Token::Service: 'static,
Try to resolve a named scoped service by its token type, returning None if not found
Sourcepub fn contains_token<Token: ServiceToken>(&self) -> bool
pub fn contains_token<Token: ServiceToken>(&self) -> bool
Check if a token is registered
Sourcepub fn contains_token_named<Token: ServiceToken>(&self, name: &str) -> bool
pub fn contains_token_named<Token: ServiceToken>(&self, name: &str) -> bool
Check if a named token is registered
Sourcepub fn token_stats(&self) -> TokenRegistryStats
pub fn token_stats(&self) -> TokenRegistryStats
Get token registry statistics
Sourcepub fn contains_named<T: 'static>(&self, name: &str) -> bool
pub fn contains_named<T: 'static>(&self, name: &str) -> bool
Check if a named service is registered
Sourcepub fn service_count(&self) -> usize
pub fn service_count(&self) -> usize
Get the number of registered services
Sourcepub fn registered_services(&self) -> Vec<ServiceId>
pub fn registered_services(&self) -> Vec<ServiceId>
Get all registered service IDs
Sourcepub fn resolve_all<T: Send + Sync + 'static>(
&self,
) -> Result<Vec<Arc<T>>, CoreError>
pub fn resolve_all<T: Send + Sync + 'static>( &self, ) -> Result<Vec<Arc<T>>, CoreError>
Resolve all implementations of an interface as a vector
Sourcepub fn resolve_all_named<T: Send + Sync + 'static>(
&self,
) -> Result<HashMap<String, Arc<T>>, CoreError>
pub fn resolve_all_named<T: Send + Sync + 'static>( &self, ) -> Result<HashMap<String, Arc<T>>, CoreError>
Resolve all implementations of an interface as a HashMap with their names
Sourcepub fn resolve_default<T: Send + Sync + 'static>(
&self,
) -> Result<Arc<T>, CoreError>
pub fn resolve_default<T: Send + Sync + 'static>( &self, ) -> Result<Arc<T>, CoreError>
Get default implementation for a type (marked with is_default in BindingConfig)
Sourcepub fn get_service_info<T: 'static>(&self) -> Option<String>
pub fn get_service_info<T: 'static>(&self) -> Option<String>
Get service information for debugging
Sourcepub fn get_registered_services(&self) -> Vec<String>
pub fn get_registered_services(&self) -> Vec<String>
Get all registered service IDs for debugging
Sourcepub fn validate_all_services(&self) -> Result<(), Vec<CoreError>>
pub fn validate_all_services(&self) -> Result<(), Vec<CoreError>>
Validate that all registered services can be resolved
Sourcepub fn get_statistics(&self) -> ServiceStatistics
pub fn get_statistics(&self) -> ServiceStatistics
Get service statistics