Skip to content
This repository was archived by the owner on Mar 15, 2025. It is now read-only.
This repository was archived by the owner on Mar 15, 2025. It is now read-only.

No examples for interior mutability except for the constant #36

@NeveHanter

Description

@NeveHanter

Hey, I started playing around with this DI container but I'm unable to achieve interior mutability. Could you provide some examples how that could be achieved with both Svc modes (Rc/Arc) and:

  • Cell,
  • RefCell,
  • Mutex,
  • RwLock,
  • or any other wrapper of any kind?

I've only found the example for constant with the Mutex in one of the docstrings:

builder.provide(constant(Mutex::new(0i32)));

I would like to be able to provide particular component wrapped for example by Mutex and then be able to retrieve this Mutex from the container.

I've created small example with comments what I would like to be able to achieve:

use runtime_injector::*;
use std::cell::{Cell, RefCell};
use std::error::Error;
use std::sync::{Mutex, RwLock};

pub trait Foo: Service {
    fn increase(&mut self);
}

#[derive(Default)]
struct FooImpl(u64);

impl Foo for FooImpl {
    fn increase(&mut self) {
        self.0 += 1;
    }
}

pub trait Bar: Service {
    fn increase(&mut self);
}

struct BarImpl {
    foo: Svc<dyn Foo>,
}

impl BarImpl {
    // Not possible to get Cell/RefCell/Mutex/RwLock
    pub fn new(foo: Svc<dyn Foo>) -> Self {
        Self { foo }
    }
}

impl Bar for BarImpl {
    fn increase(&mut self) {
        self.foo.increase();
    }
}

interface!(
    dyn Foo = [FooImpl],
    dyn Bar = [BarImpl]
);

fn main() -> Result<(), Box<dyn Error>> {
    let mut builder = Injector::builder();

    // No obvious way to allow interior mutability, like auto creation of Cell/RefCell/Mutex/RwLock
    builder.provide(FooImpl::default.singleton().with_interface::<dyn Foo>());
    builder.provide(BarImpl::new.singleton().with_interface::<dyn Bar>());

    // It could be available for example in such way:
    builder.provide(FooImpl::default.wrap_in_mutex().singleton().with_interface::<dyn Foo>());
    // or:
    builder.provide(FooImpl::default.wrap_using(|result| Mutex::new(result)).singleton().with_interface::<dyn Foo>());

    let injector = builder.build();

    // Not able to call these as they require &mut
    injector.get::<Svc<dyn Foo>>()?.increase();
    injector.get::<Svc<dyn Bar>>()?.increase();

    // No Cell/RefCell/Mutex/RwLock availability
    injector.get::<Cell<Svc<dyn Bar>>>()?.increase();
    injector.get::<RefCell<Svc<dyn Bar>>>()?.increase();
    injector.get::<Mutex<Svc<dyn Bar>>>()?.increase();
    injector.get::<RwLock<Svc<dyn Bar>>>()?.increase();

    Ok(())
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions