How to avoid cyclical addiction in this situation?

81 Views Asked by At

I have many lib crates and only one bin crate.

In the lib crates I have this simple code (different for each one):

use async_graphql::{Context, Object, Result};
use app::Services;
use std::sync::Arc;

#[derive(Default)]
pub struct PlayersQueryRoot;

#[Object]
impl PlayersQueryRoot {
    async fn players_query_root(&self, ctx: &Context<'_>) -> Result<String> {
        let res = ctx.data_unchecked::<Arc<Services>>(); // Services here is declared in `app` and imported with Cargo.toml, hence the issue

        let player = res.player_by_id.handle(1).await?;

        Ok(player.name)
    }
}

In the bin crate (called app) I have this code:

use async_graphql::{EmptyMutation, EmptySubscription, Schema};
use graphql::{GraphqlSchema, QueryRoot};
use std::sync::Arc;

pub struct Services {
    pub players: Arc<players::Service>,
    pub user: Arc<user::Service>,
}

impl Services {
    pub async fn new() -> Self {
        Self {
            user: Arc::new(user::new(/*some needed injection*/)),
            players: Arc::new(players::new(/*some needed injection*/)),
        }
    }
}

//...

pub fn create_schema(services: Arc<Services>) -> GraphqlSchema {
    Schema::build(QueryRoot::default(), EmptyMutation, EmptySubscription)
        .data(services)
        .finish()
}

It doesn't work because there is a cyclic dependency between app (bin crate) which has the lib crates as dependencies:

[dependencies]
players = { path = "../crates/players" }
users = { path = "../crates/users" }

Is there a way to fix this?

0

There are 0 best solutions below