# Volume
Ivy provides a standardized way to manage [application](./10_Apps.md) data storage through the `IVolume` interface and `FolderVolume` implementation. This ensures consistent file path handling and proper directory structure for your application's data files.
## Basic Usage
Configure a volume for your application during [server](./01_Program.md) startup:
```csharp
using Ivy.Services;
var server = new Server();
// Configure a volume for your application
var volume = new FolderVolume("/data/myapp");
server.UseVolume(volume);
await server.RunAsync();
```
### IVolume Interface
The `IVolume` interface defines the contract for volume implementations:
The `GetAbsolutePath` method combines the volume root with the specified path parts and returns the absolute path. It automatically creates parent directories if they don't exist.
```csharp
public interface IVolume
{
public string GetAbsolutePath(params string[] parts);
}
```
### Overview
The Volume Management system in Ivy provides:
- **Automatic directory creation**: Parent directories are created automatically when you request a path
- **Namespace isolation**: Files are organized under `Ivy/{YourAppName}/` to prevent conflicts between [applications](./10_Apps.md)
- **Fallback to local app data**: If the configured root directory doesn't exist, it falls back to the system's local application data folder
- **Clean path composition**: Use params array for path parts instead of manual string concatenation
- **Dependency injection support**: Volumes are registered as [services](../../03_Hooks/02_Core/11_UseService.md) and can be injected into your [views](./02_Views.md)
## FolderVolume Implementation
The `FolderVolume` class provides the standard implementation for file system volumes:
### Constructor
```csharp
public class FolderVolume(string root) : IVolume
```
- **root**: The root directory path for the volume. If this directory doesn't exist, the volume will fall back to the system's local application data folder.
### Path Structure
The `FolderVolume` creates paths in the following structure:
```text
{root}/Ivy/{YourAppName}/{pathParts}
```
Where:
- `{root}` is the configured root directory or fallback location
- `Ivy` is a fixed namespace prefix
- `{YourAppName}` is automatically derived from your application's assembly name
- `{pathParts}` are the path parts you provide to `GetAbsolutePath`
## Examples
### Using Volumes in Services
Inject and use the volume in your services:
```csharp
using Ivy.Services;
public class FileService(IVolume volume)
{
public void SaveUserData(string userId, byte[] data)
{
// Automatically creates the full path: /data/myapp/Ivy/YourAppName/users/123/profile.json
var path = volume.GetAbsolutePath("users", userId, "profile.json");
File.WriteAllBytes(path, data);
}
public byte[] LoadUserData(string userId)
{
var path = volume.GetAbsolutePath("users", userId, "profile.json");
return File.ReadAllBytes(path);
}
}
```
### Using Volumes in Views
Access volumes through [dependency injection](../../03_Hooks/02_Core/11_UseService.md) in your [views](./02_Views.md):
```csharp
public class DataManagementView : ViewBase
{
public override object? Build()
{
var volume = UseService<IVolume>();
return new Column
{
Children = [
new Button("Save Data")
{
OnClick = () => SaveData(volume)
},
new Button("Load Data")
{
OnClick = () => LoadData(volume)
}
]
};
}
private void SaveData(IVolume volume)
{
var data = Encoding.UTF8.GetBytes("Sample data");
var path = volume.GetAbsolutePath("cache", "sample.txt");
File.WriteAllBytes(path, data);
}
private void LoadData(IVolume volume)
{
var path = volume.GetAbsolutePath("cache", "sample.txt");
if (File.Exists(path))
{
var data = File.ReadAllBytes(path);
// Process data...
}
}
}
```