1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! Instance wrapper for dependency injection values.
//!
//! This module provides the [`Instance`] type, which wraps a [`Shared`] reference
//! to provide convenient access to dependency-injected values. It serves as the
//! primary interface for consuming resolved dependencies.
//!
//! # Core Responsibilities
//!
//! - **Value Access**: Provides ergonomic access to the underlying value via references
//! - **Shared Ownership**: Maintains shared ownership through reference counting
//! - **Type Safety**: Preserves type information including support for trait objects
//!
//! # Design Philosophy
//!
//! The `Instance` type is a thin wrapper around `Shared<T>` that provides a clear
//! semantic distinction between "a resolved dependency" and "a shared reference".
//! This makes the DI container's API more intuitive and self-documenting.
//!
//! # Thread Safety
//!
//! When compiled with the `thread-safe` feature, `Instance<T>` can be safely shared
//! across threads (assuming `T: Send + Sync`). The underlying `Shared` type will be
//! `Arc<T>`, providing atomic reference counting.
//!
//! # Examples
//!
//! Creating and using an instance:
//!
//! ```
//! use fluxdi::{Instance, Shared};
//!
//! struct Config {
//! debug: bool,
//! port: u16,
//! }
//!
//! let shared_config = Shared::new(Config { debug: true, port: 8080 });
//! let instance = Instance::new(shared_config);
//!
//! // Access via reference
//! assert_eq!(instance.get().port, 8080);
//!
//! // Get a cloned Shared reference
//! let shared = instance.value();
//! assert_eq!(shared.port, 8080);
//! ```
//!
//! With trait objects:
//!
//! ```
//! use fluxdi::{Instance, Shared};
//!
//! trait Logger {
//! fn log(&self, message: &str);
//! }
//!
//! struct ConsoleLogger;
//! impl Logger for ConsoleLogger {
//! fn log(&self, message: &str) {
//! println!("{}", message);
//! }
//! }
//!
//! let logger: Shared<dyn Logger> = Shared::new(ConsoleLogger);
//! let instance = Instance::<dyn Logger>::new(logger);
//!
//! instance.get().log("Hello, world!");
//! ```
use crateShared;
/// A wrapper around a shared reference to a dependency-injected value.
///
/// `Instance<T>` provides a convenient interface for accessing values resolved
/// by the dependency injection container. It maintains shared ownership of the
/// underlying value through reference counting.
///
/// # Type Parameters
///
/// - `T`: The type of the wrapped value. Can be `?Sized` to support trait objects.
///
/// # Invariants
///
/// - Always contains a valid `Shared<T>` reference
/// - The wrapped value is immutable (interior mutability requires explicit use
/// of `Mutex`, `RwLock`, `RefCell`, etc.)
///
/// # Memory Management
///
/// The instance holds a strong reference to the underlying value. The value will
/// be deallocated when all `Instance` wrappers and `Shared` references are dropped.
///
/// # Examples
///
/// Basic usage with a concrete type:
///
/// ```
/// use fluxdi::{Instance, Shared};
///
/// #[derive(Debug, PartialEq)]
/// struct User {
/// id: u32,
/// name: String,
/// }
///
/// let user = Shared::new(User {
/// id: 1,
/// name: "Alice".to_string(),
/// });
///
/// let instance = Instance::new(user);
/// assert_eq!(instance.get().id, 1);
/// assert_eq!(instance.get().name, "Alice");
/// ```
///
/// Multiple instances sharing the same value:
///
/// ```
/// use fluxdi::{Instance, Shared};
///
/// let shared = Shared::new(vec![1, 2, 3]);
/// let instance1 = Instance::new(shared.clone());
/// let instance2 = Instance::new(shared.clone());
///
/// // Both instances point to the same allocation
/// assert!(Shared::ptr_eq(&instance1.value(), &instance2.value()));
/// ```