Foundatio.DataProtection 10.7.1

前缀已保留
dotnet add package Foundatio.DataProtection --version 10.7.1                
NuGet\Install-Package Foundatio.DataProtection -Version 10.7.1                
该命令 intended to be used within the Visual Studio 的包管理器控制台,因为它使用 NuGet 模块版本的 Install-Package.
<PackageReference Include="Foundatio.DataProtection" Version="10.7.1" />                
对于支持 PackageReference 的项目,将此 XML 节点复制到项目文件中以引用包。
paket add Foundatio.DataProtection --version 10.7.1                
#r "nuget: Foundatio.DataProtection, 10.7.1"                
#r 指令可以在 F# Interactive 和 Polyglot Notebooks 中使用。将此内容复制到交互式工具或脚本的源代码中,以引用包。
// Install Foundatio.DataProtection as a Cake Addin
#addin nuget:?package=Foundatio.DataProtection&version=10.7.1

// Install Foundatio.DataProtection as a Cake Tool
#tool nuget:?package=Foundatio.DataProtection&version=10.7.1                

FoundatioFoundatio

Build status NuGet Version feedz.io Discord

用于构建松耦合分布式应用的插件化基础模块。

包括 Redis、Azure、AWS、RabbitMQ、Kafka 及内存中的实现(用于开发)。

为什么是 Foundatio?

在构建多个大型云计算应用程序时,我们发现有关于构建可扩展的分布式应用的关键要素的解决方案不足(这并不是说没有解决方案),同时保持开发体验简单。以下是几个为什么我们要构建并使用 Foundatio 的例子

  • 希望构建基于抽象接口,以便能够轻松更改实现。
  • 希望这些块易于依赖注入。
  • 缓存:我们最初使用开源的 Redis 缓存客户端,但后来它变成了具有高许可费用的商业产品。不仅如此,而且还没有内存实现,所以每个开发人员都需要设置和配置 Redis。
  • 消息总线:我们最初考虑过NServiceBus(优秀的产品),但由于许可费用高(他们也要谋生),而不是开源友好。我们还研究了MassTransit(另一个优秀的产品),但当时发现Azure支持不足,而且本地设置很繁琐(针对内存)。我们希望有一个简单的消息总线,可以在本地或云端工作。
  • 存储:我们找不到任何现有的项目,该项目既可以解耦又支持内存、文件存储或Azure Blob存储。

总结一下,如果您希望开发测试无痛苦,同时允许您的应用程序扩展,请使用Foundatio!

实现

入门(开发)

Foundatio可以通过 NuGet 包管理器进行安装。如果您需要帮助,请提交一个问题或加入我们的Discord聊天室。如果您有任何问题,我们随时都在这里帮助您!

本部分仅用于开发目的!如果您正在尝试使用Foundatio库,请从NuGet获取它们。

  1. 您需要安装Visual Studio Code
  2. 打开Foundatio.sln Visual Studio解决方案文件。

如何使用Foundatio

以下各节包含Foundatio的一些功能示例。我们建议您查看源代码以获取更多信息。如果您有任何问题或需要帮助,请告诉我们!

缓存

缓存允许您快速存储和访问数据,从而节省创建或获取数据的耗时操作。我们提供四种不同的缓存实现,它们基于ICacheClient接口

  1. InMemoryCacheClient:内存缓存客户端实现。此缓存实现仅在进程生命周期内有效。值得注意的是,内存缓存客户端可以通过MaxItems属性缓存最后X项。我们在Exceptionless中使用了它,以仅保留最后250个解析的geoip结果
  2. HybridCacheClient:此缓存实现既使用ICacheClient又使用InMemoryCacheClient,并使用IMessageBus在不同进程间保持缓存同步。如果项目存在于本地缓存中,这可以带来強大的性能提升,因为它可以节省序列化操作和对远程缓存的调用。
  3. RedisCacheClient:Redis缓存客户端实现。
  4. RedisHybridCacheClient:一个HybridCacheClient实现,使用RedisCacheClient作为ICacheClient,使用RedisMessageBus作为IMessageBus
  5. ScopedCacheClient:此缓存实现接受一个ICacheClient实例和一个字符串scope。此范围会前置到每个缓存键上。这使得对所有缓存键进行范围划分以及轻松删除它们变得非常容易。
示例
using Foundatio.Caching;

ICacheClient cache = new InMemoryCacheClient();
await cache.SetAsync("test", 1);
var value = await cache.GetAsync<int>("test");

队列

队列提供先进先出(FIFO)的消息传递。我们提供了四个不同的队列实现,这些实现都源自于IQueue接口

  1. InMemoryQueue:内存队列实现。此队列实现仅在进程的生命周期内有效。
  2. RedisQueue:Redis队列实现。
  3. AzureServiceBusQueue:Azure Service Bus 队列实现。
  4. AzureStorageQueue:Azure 存储队列实现。
  5. SQSQueue:AWS SQS 实现。
示例
using Foundatio.Queues;

IQueue<SimpleWorkItem> queue = new InMemoryQueue<SimpleWorkItem>();

await queue.EnqueueAsync(new SimpleWorkItem {
    Data = "Hello"
});

var workItem = await queue.DequeueAsync();

锁确保资源在任何给定时间只被一个消费者访问。我们提供了两个不同的锁定实现,这两个实现源自于ILockProvider接口

  1. CacheLockProvider:一个使用缓存在进程间进行通信的锁实现。
  2. ThrottlingLockProvider:一个只允许一定数量的锁通过。您可以使用此功能来限制对某些外部服务的API调用的数量,并且它将在所有请求该锁的进程中限制这些调用。
  3. ScopedLockProvider:此锁实现接受一个ILockProvider实例和一个字符串scope。此范围会前置到每个锁键上。这使得对所有锁进行范围划分以及轻松释放它们变得非常容易。

值得注意的是,所有锁提供者都接受一个ICacheClient。这允许您确保您的代码在多台机器间正确锁定。

示例
using Foundatio.Lock;

ILockProvider locker = new CacheLockProvider(new InMemoryCacheClient(), new InMemoryMessageBus());
var testLock = await locker.AcquireAsync("test");
// ...
await testLock.ReleaseAsync();

ILockProvider throttledLocker = new ThrottlingLockProvider(new InMemoryCacheClient(), 1, TimeSpan.FromMinutes(1));
var throttledLock = await throttledLocker.AcquireAsync("test");
// ...
await throttledLock.ReleaseAsync();

消息传递

允许您发布和订阅通过应用程序流动的消息。我们提供了四个不同的消息总线实现,这些实现都源自于IMessageBus接口

  1. InMemoryMessageBus:内存消息总线实现。此消息总线实现仅在进程的生命周期内有效。
  2. RedisMessageBus:Redis消息总线实现。
  3. RabbitMQMessageBus:RabbitMQ实现。
  4. KafkaMessageBus:Kafka实现。
  5. AzureServiceBusMessageBus:Azure Service Bus实现。
示例
using Foundatio.Messaging;

IMessageBus messageBus = new InMemoryMessageBus();
await messageBus.SubscribeAsync<SimpleMessageA>(msg => {
  // Got message
});

await messageBus.PublishAsync(new SimpleMessageA { Data = "Hello" });

作业

允许您在不担心进程被过早终止的情况下运行长时间运行的过程(进程内或进程外)。我们根据您的使用场景提供三种不同的定义作业的方式。

  1. 作业:所有作业都必须从IJob接口派生。我们还有一个您可以从其派生的JobBase基类,该基类提供作业上下文和日志记录。您可以通过在作业上调用RunAsync()或在创建JobRunner的实例并调用其中的运行方法来运行作业。作业运行器(JobRunner)可用来轻松地将作业作为Azure Web作业运行。
示例
using Foundatio.Jobs;

public class HelloWorldJob : JobBase {
  public int RunCount { get; set; }

  protected override Task<JobResult> RunInternalAsync(JobContext context) {
     RunCount++;
     return Task.FromResult(JobResult.Success);
  }
}
var job = new HelloWorldJob();
await job.RunAsync(); // job.RunCount = 1;
await job.RunContinuousAsync(iterationLimit: 2); // job.RunCount = 3;
await job.RunContinuousAsync(cancellationToken: new CancellationTokenSource(10).Token); // job.RunCount > 10;
  1. 队列处理作业:队列处理作业非常适合用于处理来自队列数据的作业。队列处理作业必须从QueueJobBase<T>派生。然后,您可以通过在作业上调用RunAsync()或在将其传递给JobRunner来运行作业。作业运行器(JobRunner)可用来轻松地将作业作为Azure Web作业运行。
示例
using Foundatio.Jobs;

public class HelloWorldQueueJob : QueueJobBase<HelloWorldQueueItem> {
  public int RunCount { get; set; }

  public HelloWorldQueueJob(IQueue<HelloWorldQueueItem> queue) : base(queue) {}

  protected override Task<JobResult> ProcessQueueEntryAsync(QueueEntryContext<HelloWorldQueueItem> context) {
     RunCount++;

     return Task.FromResult(JobResult.Success);
  }
}

public class HelloWorldQueueItem {
  public string Message { get; set; }
}
 // Register the queue for HelloWorldQueueItem.
container.AddSingleton<IQueue<HelloWorldQueueItem>>(s => new InMemoryQueue<HelloWorldQueueItem>());

// To trigger the job we need to queue the HelloWorldWorkItem message.
// This assumes that we injected an instance of IQueue<HelloWorldWorkItem> queue

IJob job = new HelloWorldQueueJob();
await job.RunAsync(); // job.RunCount = 0; The RunCount wasn't incremented because we didn't enqueue any data.

await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });
await job.RunAsync(); // job.RunCount = 1;

await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });
await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });
await job.RunUntilEmptyAsync(); // job.RunCount = 3;
  1. 工作项作业:工作项作业将在与其他工作项作业混合的工作池中运行。此类型的作业非常适合处理不经常发生但应包含在作业中的内容(例如:删除具有许多子实体的实体)。它将在您在message bus上发布消息时触发。作业必须从WorkItemHandlerBase派生。然后,您可以通过JobRunner运行所有共享作业。作业运行器(JobRunner)可用来轻松地将作业作为Azure Web作业运行。
示例
using System.Threading.Tasks;
using Foundatio.Jobs;

public class HelloWorldWorkItemHandler : WorkItemHandlerBase {
  public override async Task HandleItemAsync(WorkItemContext ctx) {
    var workItem = ctx.GetData<HelloWorldWorkItem>();

    // We can report the progress over the message bus easily.
    // To receive these messages just inject IMessageSubscriber
    // and Subscribe to messages of type WorkItemStatus
    await ctx.ReportProgressAsync(0, "Starting Hello World Job");
    await Task.Delay(TimeSpan.FromSeconds(2.5));
    await ctx.ReportProgressAsync(50, "Reading value");
    await Task.Delay(TimeSpan.FromSeconds(.5));
    await ctx.ReportProgressAsync(70, "Reading value");
    await Task.Delay(TimeSpan.FromSeconds(.5));
    await ctx.ReportProgressAsync(90, "Reading value.");
    await Task.Delay(TimeSpan.FromSeconds(.5));

    await ctx.ReportProgressAsync(100, workItem.Message);
  }
}

public class HelloWorldWorkItem {
  public string Message { get; set; }
}
// Register the shared job.
var handlers = new WorkItemHandlers();
handlers.Register<HelloWorldWorkItem, HelloWorldWorkItemHandler>();

// Register the handlers with dependency injection.
container.AddSingleton(handlers);

// Register the queue for WorkItemData.
container.AddSingleton<IQueue<WorkItemData>>(s => new InMemoryQueue<WorkItemData>());

// The job runner will automatically look for and run all registered WorkItemHandlers.
new JobRunner(container.GetRequiredService<WorkItemJob>(), instanceCount: 2).RunInBackground();
 // To trigger the job we need to queue the HelloWorldWorkItem message.
 // This assumes that we injected an instance of IQueue<WorkItemData> queue

 // NOTE: You may have noticed that HelloWorldWorkItem doesn't derive from WorkItemData.
 // Foundatio has an extension method that takes the model you post and serializes it to the
 // WorkItemData.Data property.
 await queue.EnqueueAsync(new HelloWorldWorkItem { Message = "Hello World" });

文件存储

我们提供不同的文件存储实现,它们从IFileStorage接口派生。

  1. InMemoryFileStorage:一个内存文件实现。此类文件存储实现仅适用于进程的有效生命周期。
  2. FolderFileStorage:一种使用硬盘进行存储的文件存储实现。
  3. AzureFileStorage:一个Azure Blob存储实现。
  4. S3FileStorage:一个AWS S3文件存储实现。
  5. RedisFileStorage:一个Redis文件存储实现。
  6. MinioFileStorage:一个Minio文件存储实现。
  7. AliyunFileStorage:一个阿里云文件存储实现。
  8. SshNetFileStorage:一个SFTP文件存储实现。

我们建议使用所有IFileStorage实现作为单例。

示例
using Foundatio.Storage;

IFileStorage storage = new InMemoryFileStorage();
await storage.SaveFileAsync("test.txt", "test");
string content = await storage.GetFileContentsAsync("test.txt")

度量

我们提供了五个从IMetricsClient接口派生的实现。

  1. InMemoryMetricsClient:一个内存指标实现。
  2. RedisMetricsClient:一个Redis指标实现。
  3. StatsDMetricsClient:statsd指标实现。
  4. MetricsNETClient:Metrics.NET实现。
  5. AppMetricsClient:AppMetrics实现。
  6. CloudWatchMetricsClient:AWS CloudWatch实现。

我们推荐将所有的IMetricsClient实现作为单例使用。

示例
IMetricsClient metrics = new InMemoryMetricsClient();
metrics.Counter("c1");
metrics.Gauge("g1", 2.534);
metrics.Timer("t1", 50788);

示例应用

我们提供了幻灯片以及示例应用,展示了如何使用Foundatio。

感谢所有贡献者

contributors

产品 兼容和额外计算的目标框架版本。
.NET net5.0已计算。 net5.0-windows已计算。 net6.0已计算。 net6.0-android已计算。 net6.0-ios已计算。 net6.0-maccatalyst已计算。 net6.0-macos已计算。 net6.0-tvos已计算。 net6.0-windows已计算。 net7.0已计算。 net7.0-android已计算。 net7.0-ios已计算。 net7.0-maccatalyst已计算。 net7.0-macos已计算。 net7.0-tvos已计算。 net7.0-windows已计算。 net8.0已计算。 net8.0-android已计算。 net8.0-browser已计算。 net8.0-ios已计算。 net8.0-maccatalyst已计算。 net8.0-macos已计算。 net8.0-tvos已计算。 net8.0-windows已计算。
.NET Core netcoreapp2.0 已计算。 netcoreapp2.1 已计算。 netcoreapp2.2 已计算。 netcoreapp3.0 已计算。 netcoreapp3.1 已计算。
.NET 标准化 netstandard2.0 兼容。 netstandard2.1 已计算。
.NET 框架 net461 已计算。 net462 已计算。 net463 已计算。 net47 已计算。 net471 已计算。 net472 已计算。 net48 已计算。 net481 已计算。
MonoAndroid monoandroid 已计算。
MonoMac monomac 已计算。
MonoTouch monotouch 已计算。
Tizen tizen40 已计算。 tizen60 已计算。
Xamarin.iOS xamarinios 已计算。
Xamarin.Mac xamarinmac 已计算。
Xamarin.TVOS xamarintvos 已计算。
Xamarin.WatchOS xamarinwatchos 已计算。
兼容的目标框架
包含的目标框架(包含在包中)
了解更多关于 目标框架.NET 标准化

NuGet 包

此包未由任何 NuGet 包使用。

GitHub 仓库

此包未由任何流行的 GitHub 仓库使用。

版本 下载 最后更新
10.7.1 2,983 3/27/2024
10.7.0 1,777 1/5/2024
10.6.1 1,199 6/23/2023
10.6.0 8,087 1/1/2023
10.5.0 1,039 5/18/2022
10.4.0 1,568 3/7/2022
10.3.1 448 1/20/2022
10.3.0 428 1/20/2022
10.2.5 468 12/7/2021
10.2.4 699 12/3/2021
10.2.3 261 11/22/2021
10.2.2 1,307 9/23/2021
10.2.1 878 7/19/2021
10.2.0 317 7/8/2021
10.1.4 381 6/16/2021
10.1.3 1,103 4/23/2021
10.1.2 323 4/23/2021
10.1.1 428 4/15/2021
10.1.0 335 4/13/2021
10.0.2 814 1/20/2021
10.0.1 1,150 11/2/2020
10.0.0 686 9/16/2020
10.0.0-beta9 599 8/25/2020
10.0.0-beta8 321 8/3/2020
10.0.0-beta7 342 7/29/2020
10.0.0-beta6 712 7/7/2020
10.0.0-beta5 486 6/20/2020
10.0.0-beta3 307 6/14/2020
10.0.0-beta2 370 6/6/2020
10.0.0-beta10 363 9/15/2020
10.0.0-beta1 340 5/26/2020
10.0.0-alpha3 306 5/5/2020
10.0.0-alpha2 321 4/27/2020
9.1.1 547 4/28/2020
9.1.0 441 4/28/2020