DependencyContext

Struct DependencyContext 

Source
pub struct DependencyContext { /* private fields */ }
Expand description

Root di context, or child context (in ctor or closure) Main component. You work with it most of the time

Implementations§

Source§

impl DependencyContext

Source

pub fn new_root() -> Self

Create new root empty context

Source

pub fn set_context(&mut self, local_context: Arc<LocalContext>)

Set saved local context

Source

pub fn set_empty_context(&mut self) -> Arc<LocalContext>

Set new local context and return copy

Source

pub fn get_context(&self) -> Arc<LocalContext>

Get copy local context.

Save local context, before set_empty_context, if you need not to lose context dependent components

Then you can restore context with set_context

Source§

impl DependencyContext

Source

pub async fn register_type<TComponent: Constructor + Sync + Send + 'static>( &self, life_cycle: LifeCycle, ) -> AddDependencyResult<ServiceMappingBuilder<TComponent>>

Register component witch implement trait Constructor

Remember, lifetime required smart pointers wrapper:

  • if register Component as Transient, resolve as Component or Box
  • if register Component as Singleton, resolve as Arc or Arc
  • if register Component as ContextDependent, resolve as Weak or Weak

Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock

§Example

From root context

struct SomeComponent {}

let root_context = DependencyContext::new_root();
root_context.register_type::<SomeComponent>(LifeCycle::Transient).await.unwrap();

From ctor context

struct SomeComponent {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        // unwrap or map error to BuildDependencyError
        ctx.register_type::<SomeComponent>(LifeCycle::Transient).await.unwrap();
        Ok(Self { })
    }
}
Source

pub async fn register_async_closure<TComponent, TFuture, TClosure>( &self, closure: TClosure, life_cycle: LifeCycle, ) -> AddDependencyResult<ServiceMappingBuilder<TComponent>>
where TComponent: Sync + Send + 'static, TFuture: Future<Output = BuildDependencyResult<TComponent>> + Sync + Send + 'static, TClosure: Fn(DependencyContext) -> TFuture + Sync + Send + 'static,

Register component from async closure

Remember, lifetime required smart pointers wrapper:

  • if register Component as Transient, resolve as Component or Box
  • if register Component as Singleton, resolve as Arc or Arc
  • if register Component as ContextDependent, resolve as Weak or Weak

Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock

§Example

From root context

struct SomeComponent {}

let root_context = DependencyContext::new_root();
root_context.register_closure(async |_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).await.unwrap();

From ctor context

struct SomeComponent {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        // unwrap or map error to BuildDependencyError
        ctx.register_closure(async |_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).await.unwrap();
        Ok(Self { })
    }
}
Source

pub async fn register_closure<TComponent: Sync + Send + 'static, TClosure: Fn(DependencyContext) -> BuildDependencyResult<TComponent> + Sync + Send + 'static>( &self, closure: TClosure, life_cycle: LifeCycle, ) -> AddDependencyResult<ServiceMappingBuilder<TComponent>>

Register component from closure

Remember, lifetime required smart pointers wrapper:

  • if register Component as Transient, resolve as Component or Box
  • if register Component as Singleton, resolve as Arc or Arc
  • if register Component as ContextDependent, resolve as Weak or Weak

Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock

§Example

From root context

struct SomeComponent {}

let root_context = DependencyContext::new_root();
root_context.register_closure(|_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).await.unwrap();

From ctor context

struct SomeComponent {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        // unwrap or map error to BuildDependencyError
        ctx.register_closure(|_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).await.unwrap();
        Ok(Self { })
    }
}
Source

pub async fn register_instance<TComponent: Sync + Send + 'static>( &self, instance: TComponent, ) -> AddDependencyResult<ServiceMappingBuilder<TComponent>>

Register component instance as singleton

Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock

§Example

From root context

struct SomeComponent {}

let root_context = DependencyContext::new_root();
root_context.register_instance::<SomeComponent>(SomeComponent::new()).await.unwrap();

From ctor context

struct SomeComponent {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        // unwrap or map error to BuildDependencyError
        ctx.register_instance::<SomeComponent>(SomeComponent::new()).await.unwrap();
        Ok(Self { })
    }
}
Source

pub async fn map_component<TComponent, TService: ?Sized + Sync + Send + 'static>( &self, ) -> MapComponentResult<Arc<CoreContext>>
where TComponent: Unsize<TService> + Sync + Send + 'static,

Map component as service

§Example

From root context

struct SomeComponent {}
trait SomeService {}

let root_context = DependencyContext::new_root();
//...

// SomeComponent must be registered, or will be error
root_context.map_component::<SomeComponent, dyn SomeService>().await.unwrap();

From ctor context

struct SomeComponent {}
trait SomeService {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        // SomeComponent must be registered, or will be error
        // unwrap or map error to BuildDependencyError
        ctx.map_component::<SomeComponent, dyn SomeService>().await.unwrap();
        Ok(Self { })
    }
}
Source

pub async fn resolve<'a, TService: Sync + Send + 'static>( &'a self, ) -> BuildDependencyResult<TService>

Resolve first component, mapped to service

// You can resolve transient like:
ctx.resolve::<Box<dyn Service>>().await.unwrap()
ctx.resolve::<Box<Component>>().await.unwrap()

// You can resolve singleton like:
ctx.resolve::<Arc<dyn Service>>().await.unwrap()
ctx.resolve::<Arc<Component>>().await.unwrap()

// You can resolve context dependent like:
ctx.resolve::<Weak<dyn Service>>().await.unwrap()
ctx.resolve::<Weak<Component>>().await.unwrap()

// for mutable Arc and Weak, register as RwLock<Component>, map as RwLock<dyn Service>, and resolve like:
ctx.resolve::<Weak<RwLock<dyn Service>>>().await.unwrap()
 
§Example

From root context

trait SomeService {}

let root_context = DependencyContext::new_root();
let service: Box<dyn SomeTrait> = root_context.resolve::<Box<dyn SomeService>>().await.unwrap();

From ctor context

trait SomeService {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        // unwrap or map error to BuildDependencyError
        let service: Box<dyn SomeTrait> = ctx.resolve::<Box<dyn SomeService>>().await.unwrap();
        Ok(Self { })
    }
}
Source

pub async fn resolve_by_type_id<TService: Sync + Send + 'static>( &self, component_type_id: TypeId, ) -> BuildDependencyResult<TService>

Resolve component with TypeId, mapped to service That may be helpful in case, when you need current component, type is lost, but you can save TypeId as variable

// You can resolve transient like:
ctx.resolve_by_type_id::<Box<dyn Service>>(TypeId::of::<Component>()).await.unwrap()
ctx.resolve_by_type_id::<Box<Component>>(TypeId::of::<Component>()).await.unwrap()

// You can resolve singleton like:
ctx.resolve_by_type_id::<Arc<dyn Service>>(TypeId::of::<Component>()).await.unwrap()
ctx.resolve_by_type_id::<Arc<Component>>(TypeId::of::<Component>()).await.unwrap()

// You can resolve context dependent like:
ctx.resolve_by_type_id::<Weak<dyn Service>>(TypeId::of::<Component>()).await.unwrap()
ctx.resolve_by_type_id::<Weak<Component>>(TypeId::of::<Component>()).await.unwrap()

// for mutable Arc and Weak, register as RwLock<Component>, map as RwLock<dyn Service>, and resolve like:
ctx.resolve_by_type_id::<Weak<RwLock<dyn Service>>>(TypeId::of::<Component>()).await.unwrap()
 
§Example

From root context

struct SomeComponent {}
trait SomeService {}

let root_context = DependencyContext::new_root();
let service: Box<dyn SomeTrait> = root_context.resolve_by_type_id::<Box<dyn SomeService>>(TypeId::of::<SomeComponent>()).await.unwrap();

From ctor context

struct SomeComponent {}
trait SomeService {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        // unwrap or map error to BuildDependencyError
        let service: Box<dyn SomeTrait> = ctx.resolve_by_type_id::<Box<dyn SomeService>>(TypeId::of::<SomeComponent>()).await.unwrap();
        Ok(Self { })
    }
}
Source

pub async fn resolve_collection<TService: Sync + Send + 'static>( &self, ) -> BuildDependencyResult<Vec<TService>>

Resolve all component, mapped to service

// You can resolve transient like:
ctx.resolve_collection::<Box<dyn Service>>().await.unwrap()
ctx.resolve_collection::<Box<Component>>().await.unwrap()

// You can resolve singleton like:
ctx.resolve_collection::<Arc<dyn Service>>().await.unwrap()
ctx.resolve_collection::<Arc<Component>>().await.unwrap()

// You can resolve context dependent like:
ctx.resolve_collection::<Weak<dyn Service>>().await.unwrap()
ctx.resolve_collection::<Weak<Component>>().await.unwrap()

// for mutable Arc and Weak, register as RwLock<Component>, map as RwLock<dyn Service>, and resolve like:
ctx.resolve_collection::<Weak<RwLock<dyn Service>>>().await.unwrap()
 
§Example

From root context

trait SomeService {}

let root_context = DependencyContext::new_root();
let collection: Vec<Box<dyn SomeService>> = root_context.resolve_collection::<Box<dyn SomeService>>().await.unwrap();

From ctor context

trait SomeService {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        // unwrap or map error to BuildDependencyError
        let collection: Vec<Box<dyn SomeService>> = ctx.resolve_collection::<Box<dyn SomeService>>().await.unwrap();
        Ok(Self { })
    }
}
Source

pub async fn delete_component<TComponent: 'static>( &self, ) -> DeleteComponentResult<()>

Delete component

§Example

From root context

struct SomeComponent {}

let root_context = DependencyContext::new_root();
root_context.delete_component::<SomeComponent>().await.unwrap();

From ctor context

struct SomeComponent {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        // unwrap or map error to BuildDependencyError
        ctx.delete_component::<SomeComponent>().await.unwrap();
        Ok(Self { })
    }
}
Source

pub async fn is_service_exist<TService: 'static>(&self) -> bool

Check service existence

// You can check transient like:
ctx.is_service_exist::<Box<dyn Service>>().await.unwrap()
ctx.is_service_exist::<Box<Component>>().await.unwrap()

// You can check singleton like:
ctx.is_service_exist::<Arc<dyn Service>>().await.unwrap()
ctx.is_service_exist::<Arc<Component>>().await.unwrap()

// You can check context dependent like:
ctx.is_service_exist::<Weak<dyn Service>>().await.unwrap()
ctx.is_service_exist::<Weak<Component>>().await.unwrap()

// remember, if you register as RwLock<Component>, map as RwLock<dyn Service>, check like:
ctx.is_service_exist::<Weak<RwLock<dyn Service>>>().await.unwrap()
 
§Example

From root context

trait SomeService {}

let root_context = DependencyContext::new_root();
let is_exist: bool = root_context.is_service_exist::<Box<dyn SomeService>>().await;

From ctor context

trait SomeService {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        let is_exist: bool = ctx.is_service_exist::<Box<dyn SomeService>>().await;
        Ok(Self { })
    }
}
Source

pub async fn is_service_with_type_id_exist( &self, service_type_id: TypeId, ) -> bool

Check service existence by type id

// You can check transient like:
ctx.is_service_with_type_id_exist(TypeId::of::<Box<dyn Service>>()).await.unwrap()
ctx.is_service_with_type_id_exist(TypeId::of::<Box<Component>>()).await.unwrap()

// You can check singleton like:
ctx.is_service_with_type_id_exist(TypeId::of::<Arc<dyn Service>>()).await.unwrap()
ctx.is_service_with_type_id_exist(TypeId::of::<Arc<Component>>()).await.unwrap()

// You can check context dependent like:
ctx.is_service_with_type_id_exist(TypeId::of::<Weak<dyn Service>>()).await.unwrap()
ctx.is_service_with_type_id_exist(TypeId::of::<Weak<Component>>()).await.unwrap()

// remember, if you register as RwLock<Component>, map as RwLock<dyn Service>, check like:
ctx.is_service_with_type_id_exist(TypeId::of::<Weak<RwLock<dyn Service>>>()).await.unwrap()
 
§Example

From root context

trait SomeService {}

let root_context = DependencyContext::new_root();
let is_exist: bool = root_context.is_service_with_type_id_exist(TypeId::of::<Box<dyn SomeService>>()).await;

From ctor context

trait SomeService {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        let is_exist: bool = ctx.is_service_with_type_id_exist(TypeId::of::<Box<dyn SomeService>>()).await;
        Ok(Self { })
    }
}
Source

pub async fn is_component_exist<TComponent: 'static>(&self) -> bool

Check component existence

§Example

From root context

struct SomeComponent {}

let root_context = DependencyContext::new_root();
let is_exist: bool = root_context.is_component_exist::<SomeComponent>().await;

From ctor context

struct SomeComponent {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        let is_exist: bool = ctx.is_component_exist::<SomeComponent>().await;
        Ok(Self { })
    }
}
Source

pub async fn is_component_with_type_id_exist( &self, component_type_id: TypeId, ) -> bool

Check component existence by type id

§Example

From root context

struct SomeComponent {}

let root_context = DependencyContext::new_root();
let is_exist: bool = root_context.is_component_with_type_id_exist(TypeId::of::<SomeComponent>()).await;

From ctor context

struct SomeComponent {}

#[async_trait_with_sync::async_trait(Sync)]
impl Constructor for SomeOtherComponent {
    async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
        let is_exist: bool = ctx.is_component_with_type_id_exist(TypeId::of::<SomeComponent>()).await;
        Ok(Self { })
    }
}

Trait Implementations§

Source§

impl Clone for DependencyContext

Source§

fn clone(&self) -> DependencyContext

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DependencyContext

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.