lilydocs
HTTP APIWebSocketConsumer
Temeller3 dk okuma

Servisler ve injection

Paylaşılan bağımlılıkları controller’a, mesaj boyunca yaşayan servisleri aktif DI scope’una bağlayın.

Lily HTTP, WebSocket ve Consumer ortak DI altyapısını kullanır. lily_injection container ve scope'ları, lily_injectable_derive servis kaydını, lily_injection_registry kayıt altyapısını sağlar.

Bağımlılıklar#

İlk uygulamadaki bağımlılık yeterlidir:

TOML
lilyrs = { version = "0.1.0", features = ["websocket"] }

Injectable, ServiceTrait, InjectionError, container ve scope tiplerini lilyrs::websocket üzerinden alın. Makrolar facade'i bulur; lily_injectable_derive, lily_injection_registry, lily_error ve linkme uygulamanıza ayrıca eklenmez. Registry, link-time keşfin iç altyapısı olarak kalır; manuel servis listesi yazmayın. Servis modülünü uygulamanın derlenen modül ağacına dahil edin.

Framework'ten bağımsız bir servis kütüphanesi yazıyorsanız features = ["injection"] seçip lilyrs::injection::{Injectable, ServiceTrait, InjectionError} kullanın. websocket feature'ının DI'yı içeride etkinleştirmesi public lilyrs::injection modülünü açmaz. lilyrs::di veya private expansion yollarını kullanmayın. BaseGateway, doğrudan crate yolları üreten ayrı bir makro olduğu için kendi bağımlılık istisnasını açıkça tanımlar.

Constructor ve mesaj injection’ı#

Bu örneği src/di.rs olarak kaydedip crate köküne mod di; ekleyin:

di.rs
use std::sync::Arc;
use lilyrs::websocket::Injectable;
use lilyrs::websocket::ServiceTrait;
use lilyrs::websocket::{Ack, Extensions, Service, WebSocketActionError, WebSocketController,
    WebSocketControllerInitError, WebSocketControllerTrait, async_trait, websocket_controller};

#[derive(Injectable)]
#[service(lifetime = "Singleton")]
struct GreetingPolicy;
impl ServiceTrait for GreetingPolicy {}

#[derive(Injectable)]
#[service(lifetime = "Scoped")]
struct GreetingService {
    #[inject]
    policy: Arc<GreetingPolicy>,
}
impl ServiceTrait for GreetingService {}

impl GreetingService {
    fn greeting(&self) -> String { "Merhaba".into() }
}

#[derive(WebSocketController)]
#[namespace("greetings")]
struct GreetingController { policy: Arc<GreetingPolicy> }

#[async_trait]
impl WebSocketControllerTrait for GreetingController {
    async fn new(extensions: Arc<Extensions>) -> Result<Self, WebSocketControllerInitError> {
        let policy = extensions.get_service::<GreetingPolicy>(None).await
            .map_err(WebSocketControllerInitError::dependency)?;
        Ok(Self { policy })
    }
}

#[websocket_controller]
impl GreetingController {
    #[message("read")]
    async fn read(&self, Service(service): Service<GreetingService>)
        -> Result<Ack<String>, WebSocketActionError>
    { Ok(Ack::new(service.greeting())) }
}

Tam örnek dosyasını indirin.

GreetingPolicy Singleton'dır; constructor'da extensions.get_service::<GreetingPolicy>(None) ile çözülür. Controller app boyunca bu instance'ı paylaşabilir. GreetingService Scoped'dur; Service<GreetingService> extractor'ı onu greetings:read mesajının aktif scope'undan alır.

Aynı scope içinde paylaşım#

Aynı mesajdaki middleware, guard ve action aynı Scoped servisi çözerse aynı örneği kullanır. Sonraki mesaj için yeni scope açılır. Controller constructor'ı mesaj scope'unda çalışmadığından Scoped servisi controller alanına koymayın.

Service<T> bir parts extractor'dır. Action imzasında payload'dan sonra yazılması önce çözülmesini engellemez; framework bütün parts extraction'ı payload tüketiminden önce yapar.

Başlatma ve temizlik#

Async kaynak açılışı ServiceTrait::initialize(&mut self), cleanup ise dispose(&self) içindedir. Controller, guard ve middleware için ayrı async dispose callback'i yoktur; veritabanı veya bağlantı gibi yönetilen kaynakları DI servisine yerleştirin.

Lifetime belirtilmezse Transient seçilir. Rehberde niyeti görünür kılmak için lifetime açık yazılır. Bütün named alanlar inject ediliyorsa Default gerekmez; inject edilmeyen runtime alanlarının ilk değerlerini üretmek için Default gerekir. Scope ve interface sayfası paylaşım sınırlarını ayrıntılandırır.

Bu sayfanın kaynakları v0.1.0

Anlatım, incelenen framework commit’ine dayanır.

HIZLI BAŞLANGIÇ
Dokümantasyon
Kaynak kod