Skip to main content

rust_webx_core/mediator/
default.rs

1//! IMediator implementation.
2//!
3//! `Mediator::send` delegates to the shared [`dispatch`](super::dispatch::dispatch)
4//! function — the same path used by HTTP endpoint adapters after request construction.
5//!
6//! `Mediator::publish` resolves `IEventHandler<T>` from the DI container and
7//! invokes all registered handlers.
8
9use std::sync::Arc;
10
11use rust_dix::ScopeFactory;
12
13use super::dispatch;
14use super::{IEventRequest, IMediator, IRequest};
15use crate::error::Result;
16use crate::handler::IEventHandler;
17
18/// Default implementation of IMediator.
19///
20/// Holds a reference to the root `ServiceProvider`. Each `send` call creates
21/// a per-request scope so Scoped services (e.g. DbContext) are resolved fresh.
22pub struct Mediator {
23    provider: Arc<rust_dix::ServiceProvider>,
24}
25
26impl Mediator {
27    pub fn new(provider: Arc<rust_dix::ServiceProvider>) -> Self {
28        Self { provider }
29    }
30}
31
32#[async_trait::async_trait]
33impl IMediator for Mediator {
34    async fn send<T, R>(&self, req: T) -> Result<R>
35    where
36        T: IRequest<R> + Send + 'static,
37        R: serde::Serialize + Send + 'static,
38    {
39        dispatch::dispatch(&self.provider, req).await
40    }
41
42    async fn publish<T: IEventRequest>(&self, event: T) -> Result<()> {
43        let scope = self.provider.create_scope();
44        let handlers: Vec<Arc<dyn IEventHandler<T>>> = scope.get_all::<dyn IEventHandler<T>>();
45
46        for handler in handlers {
47            handler.handle(event.clone()).await?;
48        }
49
50        Ok(())
51    }
52}