Dependency Injection in Rust
This crate provides integration support between coi
and actix-web
. It
exposes an inject
procedural attribute macro to generate the code for
retrieving your dependencies from a Container
registered with actix-web
.
```rust,norun // What this crate provides use coiactix_web::inject;
// What's needed for the example fn below use actix_web::{get, web::{self, HttpResponse}, Responder}; use std::sync::Arc;
// Add the inject
attribute to the function you want to inject
async fn get(
id: web::Path // Just data models for the above fn
use serde::Serialize; struct DataDto {
name: String,
} impl DataDto {
fn from(data: Data) -> Self {
Self {
name: data.name
}
}
} // An example of what's usually needed to make effective use of this
// crate is below
use coi::Inject;
use futures::future::{ready, BoxFuture}; // This section shows coi being put to use
// It's very important that the version of coi and the version
// of coi-actix-web used match since coi-actix-web implements
// some coi traits // Here we're marking a trait as injectable
trait IService: Inject {
fn get(&self, id: u64) -> BoxFuture // And here we're marking a type that's capable of providing the
// above trait struct ServiceImpl {
// Here we're injecting a dependency. // Normal impl for struct
impl ServiceImpl {
fn new(repo: Arc // Normal impl of trait for struct
impl IService for ServiceImpl {
fn get(&self, id: u64) -> BoxFuture // The data that will be passed between services
struct Data {
id: u64,
name: String,
} // Here's the trait from above
trait IRepo: Inject {
fn readfromdb(&self, id: u64) -> BoxFuture // And it's setup below struct RepoImpl; impl IRepo for RepoImpl {
fn readfromdb(&self, id: u64) -> BoxFuture // This is for the registercontainer function
use coiactix_web::AppExt as _; // Your general server setup in "main". The name here is different async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer};
use coi::container; }
``` See the repo [
Licensed under either of Apache License, Version
2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
be dual licensed as above, without any additional terms or conditions.
inject
field attribute to each attribute you want
// injected
#[inject] service: Arc[derive(Serialize)]
[derive(Inject)]
[coi(provides dyn IService with ServiceImpl::new(repo))]
ServiceImpl
does
// not need to know how to get this value.
#[coi(inject)]
repo: Arc[derive(Inject)]
[coi(provides dyn IRepo with RepoImpl)]
[actix_rt::main]
// Construct your coi container with your keys and providers
// See the coi crate for more details
let container = container!{
repo => RepoImplProvider; scoped,
service => ServiceImplProvider; scoped
};
HttpServer::new(move || {
App::new()
// Don't forget to register the container or else
// the injections will fail on every request!
.register_container(container.clone())
.service(get)
})
.bind("127.0.0.1:8000")?
.run()
.await
coi-actix-sample
] for a more involved example.License
SPDX-License-Identifier: MIT OR Apache-2.0