feat(website): update home page to showcase CherryPick DI documentation

- Replaced the main action button text with 'Explore CherryPick Documentation 🍒' instead of 'Docusaurus Tutorial'.
- Updated the button link to target /docs/intro (main docs entry point).
- Changed <Layout> props:
  - Page title now uses project title only (siteConfig.title)
  - Added a CherryPick-related site description for better SEO and context.
- The homepage is now tailored to reflect CherryPick's purpose as a Dart & Flutter DI library instead of Docusaurus boilerplate.
This commit is contained in:
Sergey Penkovsky
2025-08-14 13:41:54 +03:00
parent f4c4fe49a0
commit 248bf4c8c5
44 changed files with 770 additions and 710 deletions

View File

@@ -0,0 +1,4 @@
{
"label": "Core Concepts",
"position": 4
}

View File

@@ -0,0 +1,41 @@
---
sidebar_position: 1
---
# Binding
A **Binding** acts as a configuration for how to create or provide a particular dependency. Bindings support:
* Direct instance assignment (`toInstance()`, `toInstanceAsync()`)
* Lazy providers (sync/async functions)
* Provider functions supporting dynamic parameters
* Named instances for resolving by string key
* Optional singleton lifecycle
## Example
```dart
// Provide a direct instance
Binding<String>().toInstance("Hello world");
// Provide an async direct instance
Binding<String>().toInstanceAsync(Future.value("Hello world"));
// Provide a lazy sync instance using a factory
Binding<String>().toProvide(() => "Hello world");
// Provide a lazy async instance using a factory
Binding<String>().toProvideAsync(() async => "Hello async world");
// Provide an instance with dynamic parameters (sync)
Binding<String>().toProvideWithParams((params) => "Hello $params");
// Provide an instance with dynamic parameters (async)
Binding<String>().toProvideAsyncWithParams((params) async => "Hello $params");
// Named instance for retrieval by name
Binding<String>().toProvide(() => "Hello world").withName("my_string");
// Mark as singleton (only one instance within the scope)
Binding<String>().toProvide(() => "Hello world").singleton();
```

View File

@@ -0,0 +1,52 @@
---
sidebar_position: 4
---
# Disposable
CherryPick can automatically clean up any dependency that implements the `Disposable` interface. This makes resource management (for controllers, streams, sockets, files, etc.) easy and reliable—especially when scopes or the app are shut down.
If you bind an object implementing `Disposable` as a singleton or provide it via the DI container, CherryPick will call its `dispose()` method when the scope is closed or cleaned up.
## Key Points
- Supports both synchronous and asynchronous cleanup (dispose may return `void` or `Future`).
- All `Disposable` instances from the current scope and subscopes will be disposed in the correct order.
- Prevents resource leaks and enforces robust cleanup.
- No manual wiring needed once your class implements `Disposable`.
## Minimal Sync Example
```dart
class CacheManager implements Disposable {
void dispose() {
cache.clear();
print('CacheManager disposed!');
}
}
final scope = CherryPick.openRootScope();
scope.installModules([
Module((bind) => bind<CacheManager>().toProvide(() => CacheManager()).singleton()),
]);
// ...later
await CherryPick.closeRootScope(); // prints: CacheManager disposed!
```
## Async Example
```dart
class MyServiceWithSocket implements Disposable {
@override
Future<void> dispose() async {
await socket.close();
print('Socket closed!');
}
}
scope.installModules([
Module((bind) => bind<MyServiceWithSocket>().toProvide(() => MyServiceWithSocket()).singleton()),
]);
await CherryPick.closeRootScope(); // awaits async disposal
```
**Tip:** Always call `await CherryPick.closeRootScope()` or `await scope.closeSubScope(key)` in your shutdown/teardown logic to ensure all resources are released automatically.

View File

@@ -0,0 +1,19 @@
---
sidebar_position: 2
---
# Module
A **Module** is a logical collection point for bindings, designed for grouping and initializing related dependencies. Implement the `builder` method to define how dependencies should be bound within the scope.
## Example
```dart
class AppModule extends Module {
@override
void builder(Scope currentScope) {
bind<ApiClient>().toInstance(ApiClientMock());
bind<String>().toProvide(() => "Hello world!");
}
}
```

View File

@@ -0,0 +1,31 @@
---
sidebar_position: 3
---
# Scope
A **Scope** manages a tree of modules and dependency instances. Scopes can be nested into hierarchies (parent-child), supporting modular app composition and context-specific overrides.
You typically work with the root scope, but can also create named subscopes as needed.
## Example
```dart
// Open the main/root scope
final rootScope = CherryPick.openRootScope();
// Install a custom module
rootScope.installModules([AppModule()]);
// Resolve a dependency synchronously
final str = rootScope.resolve<String>();
// Resolve a dependency asynchronously
final result = await rootScope.resolveAsync<String>();
// Recommended: Close the root scope and release all resources
await CherryPick.closeRootScope();
// Alternatively, you may manually call dispose on any scope you manage individually
// await rootScope.dispose();
```