実践 axum
axum でなにがしを実装する際のメモ
Dependencies Injection
依存性の注入をするときに単純な静的ディスパッチを使用するのか, Cake Pattern を使用するのか色々考えたが, Cake Pattern だと 最後に全ての Trait を実装する Module
があらゆる機能が露出してしまう(例えば Repository のインターフェイスが露出してしまう, 他のユースケースが必要のない Repository を呼び出せてしまうなど)のが問題である。
一応 Trait を use
しなければ呼び出せない。
trait Repository {
fn read(&self, id: i32) -> String;
}
struct RepositoryImpl {}
impl Repository for RepositoryImpl {
fn read(&self, _id: i32) -> String {
"data".to_string()
}
}
pub trait Service {
fn get_data(&self, id: i32) -> String;
}
struct ServiceImpl<R: Repository> {
repo: R,
}
impl<R: Repo> ServiceImpl<R> {
pub fn new(repo: R) -> Self {
Self { repo }
}
}
impl<R: Repo> Service for ServiceImpl<R> {
fn get(&self, id: i32) -> String {
self.repo.get(id)
}
}
pub trait HasService {
type S1: Service;
fn service(&self) -> &Self::S1;
}
pub struct Module<S: Service> {
pub service: S,
}
impl<S: Service> Module<S> {
pub fn new(service: S) -> Self {
Self { service }
}
}
impl<S: Service> HasService for Module<S> {
type S1 = S;
fn service(&self) -> &Self::S1 {
&self.service
}
}
// -- fn --
pub fn get<M: HasService>(module: M, id: i32) -> String {
module.service().get(id)
}