MoneyTree.Storage.AliyunOss 1.0.4

MoneyTree.Storage 文件存储

📋 概述

MoneyTree.Storage 提供统一的文件存储抽象层,屏蔽底层云服务商差异。开发者通过 IFileStorage 接口操作文件,支持本地磁盘、MinIO、阿里云 OSS、腾讯云 COS 和七牛云等多种后端,切换提供者只需改配置无需改代码。

属性 说明
NuGet 包 MoneyTree.Storage
外部依赖 MoneyTree.Core
定位 统一文件存储抽象与多云后端集成

📦 包体系结构

MoneyTree.Storage                            ← 核心包:IFileStorage 接口 + 本地存储
    ├── MoneyTree.Storage.Minio              ← 扩展包:MinIO 对象存储
    ├── MoneyTree.Storage.AliyunOss          ← 扩展包:阿里云 OSS
    ├── MoneyTree.Storage.TencentCos         ← 扩展包:腾讯云 COS
    └── MoneyTree.Storage.Qiniu              ← 扩展包:七牛云存储

🏗️ 项目文件结构

MoneyTree.Storage/
├── MoneyTree.Storage.csproj
├── GlobalUsings.cs
├── Abstractions/
│   └── IFileStorage.cs                     # 统一文件存储接口
├── Core/
│   ├── FileStorageOptions.cs               # 全局配置选项
│   └── FileMetadata.cs                     # 文件元数据模型
├── Providers/
│   └── LocalFileStorage.cs                 # 本地磁盘存储
└── Extensions/
    ├── StorageBuilder.cs                   # 流畅配置构造器
    └── StorageExtensions.cs                # DI 注册扩展

🎯 设计原则

原则 说明
统一接口 所有提供者实现同一个 IFileStorage,切换提供者只需改配置
流式处理 上传/下载均使用 Stream,避免大文件撑爆内存
元数据丰富 自动记录文件名、大小、MIME 类型、MD5 哈希、上传时间
URL 生成 支持预签名 URL(私有 Bucket)和公开 URL

🚀 快速开始

本地存储(开发环境)

// Program.cs
using MoneyTree.Storage.Extensions;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMoneyTreeStorage(s => s.UseLocal("./uploads"));

MinIO 存储

builder.Services.AddMoneyTreeStorage(s =>
{
    s.UseMinio(
        endpoint: "minio.example.com:9000",
        accessKey: "your-key",
        secretKey: "your-secret",
        bucketName: "myapp",
        useSsl: true);
});

阿里云 OSS

builder.Services.AddMoneyTreeStorage(s =>
{
    s.UseAliyunOss(
        endpoint: "oss-cn-hangzhou.aliyuncs.com",
        accessKeyId: "your-ak",
        accessKeySecret: "your-sk",
        bucketName: "my-bucket");
});

腾讯云 COS

builder.Services.AddMoneyTreeStorage(s =>
{
    s.UseTencentCos(
        region: "ap-guangzhou",
        secretId: "your-secret-id",
        secretKey: "your-secret-key",
        bucketName: "my-bucket");
});

七牛云

builder.Services.AddMoneyTreeStorage(s =>
{
    s.UseQiniu(
        accessKey: "your-ak",
        secretKey: "your-sk",
        bucketName: "my-bucket",
        baseUrl: "https://cdn.example.com");
});

📖 使用示例

文件上传

public class AvatarService
{
    private readonly IFileStorage _storage;

    public AvatarService(IFileStorage storage)
    {
        _storage = storage;
    }

    public async Task<string> UploadAvatarAsync(string userId, Stream image)
    {
        var key = $"avatars/{userId}.jpg";
        var metadata = await _storage.UploadAsync(key, image, "image/jpeg");
        return await _storage.GetPublicUrlAsync(key);
    }
}

文件下载终结点

app.MapGet("/api/files/{**key}", async (string key, IFileStorage storage) =>
{
    var stream = await storage.DownloadAsync(key);
    if (stream is null) return Results.NotFound();

    var metadata = await storage.GetMetadataAsync(key);
    return Results.File(stream, metadata?.ContentType ?? "application/octet-stream");
});

文件删除和列表

// 删除文件
await _storage.DeleteAsync("avatars/user-001.jpg");

// 列出目录下的所有文件
var files = await _storage.ListAsync("avatars/");

// 获取文件元数据
var metadata = await _storage.GetMetadataAsync("reports/monthly.xlsx");

📋 IFileStorage 接口说明

方法 说明
UploadAsync(key, stream, contentType) 上传文件,返回元数据
DownloadAsync(key) 下载文件流
DeleteAsync(key) 删除文件
DeleteAsync(keys) 批量删除文件
ListAsync(prefix) 列出指定前缀的文件列表
GetMetadataAsync(key) 获取文件元数据
GetPublicUrlAsync(key) 获取公开访问 URL
GetPresignedUrlAsync(key, expiry) 生成预签名 URL(私有 Bucket)
ExistsAsync(key) 检查文件是否存在

📊 FileMetadata 元数据模型

属性 类型 说明
Key string 文件唯一标识(路径)
FileName string 文件名称
ContentType string MIME 类型
Size long 文件大小(字节)
Md5Hash string? MD5 哈希值
UploadedAt DateTime 上传时间
LastModified DateTime 最后修改时间
StorageProvider string 存储提供者名称

🔌 存储后端对比

后端 开发环境 生产环境 特点
本地磁盘 ✅ 推荐 零依赖,快速启动
MinIO 开源,S3 兼容,可自建
阿里云 OSS 国内主流,CDN 加速
腾讯云 COS 国内主流,数据处理
七牛云 CDN 加速,图片处理

No packages depend on MoneyTree.Storage.AliyunOss.

.NET 10.0

Version Downloads Last updated
1.0.4 1 7/21/2026
1.0.3 1 7/12/2026