Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for dependency's field injection. #1

Closed
zooeywm opened this issue Aug 13, 2023 · 3 comments
Closed

Support for dependency's field injection. #1

zooeywm opened this issue Aug 13, 2023 · 3 comments

Comments

@zooeywm
Copy link

zooeywm commented Aug 13, 2023

When inject a specific field from a struct, for example, I think it would be better to code like this:

// Register async function and specify name
#[Singleton(name = "number")]
async fn Number() -> u32 {
    42
}

#[derive(Debug, Clone)]
#[Singleton(name = "config")] // Register async constructor and specify name
struct Config{
    #[di(name = "number")] // Specify the name of the dependency
    max_user: u32,
}

#[derive(Debug)]
struct Bar(i32);

impl Bar {
    fn into_debug(self) -> Rc<dyn Debug> {
        Rc::new(self)
    }
}

#[Transient(binds = [Self::into_debug])] // Bind the implementation of the `Debug` trait and the trait object of the `Debug` trait
impl Bar {
    async fn new(#[di(name = "config.max_user")] max_user: u32) -> Bar { // Register async constructor
        Bar(max_user)
    }
}
@ZihanType
Copy link
Owner

In the above example, there are 3 things worth noting.

  1. #[di(name = "number")] max_user: u32,, which is written to find the instance with name "number" and type u32 from the Context, not to register this instance to the Context.

  2. Config is registered to Context as a whole, its internal fields are not registered to Context.

  3. #[di(name = "config.max_user")] max_user: u32, which is written in such a way that it is trying to find an instance with the name "config.max_user" and type u32 from the Context, is not found.

@zooeywm
Copy link
Author

zooeywm commented Aug 13, 2023

Thanks for your reply, I can understand the things you list, my understanding was also the same as you when I first raised the issue.
My issue isn't a problem, it is an possibly “enhance”

#[di(name = "config.max_user")] max_user: u32, which is written in such a way that it is trying to find an instance with the name "config.max_user" and type u32 from the Context, is not found.

In my imagine with this thing: #[di(name = "config.max_user")] max_user: u32:
If the Context can recognize the . symbol as a signal to look for max_user field of the whole registered Config with a dependency-name "config", then extract the max_user field here, would be better than this:

#[derive(Debug)]
struct Bar(Config);

#[Transient(binds = [Self::into_debug])] // Bind the implementation of the `Debug` trait and the trait object of the `Debug` trait
impl Bar {
    async fn new(#[di(name = "config")] config: Config) -> Bar { // Register async constructor
        Bar(config.max_user)
    }
}

@ZihanType
Copy link
Owner

All instances stored in the Context are of type Box<dyn Any>, and the corresponding instance cannot be found by a name "config.max_user" or "config" alone. You have to use the name plus the type as a unique key to find the corresponding Box<dyn Any> instance, and then convert it to an instance of a specific type. So #[di(name = "config")] config: Config works, #[di(name = "config.max_user")] max_user: u32 does not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants