Foundatio.MessagePack 10.7.1

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

// Install Foundatio.MessagePack as a Cake Tool
#tool nuget:?package=Foundatio.MessagePack&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!

实现

入门指南(开发)

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

本节仅为开发目的。如果您正在尝试使用Foundatio库,请从NuGet获取。

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

使用Foundatio

以下部分仅包含Foundatio可能实现的一小部分功能。我们建议您查看源代码以获取更多信息。如果您有任何问题或需要帮助,请告知我们!

缓存

缓存可以让您快速存储和访问数据,从而节省创建或获取数据的高昂操作成本。我们提供了四种不同的缓存实现,它们基于ICacheClient接口

  1. InMemoryCacheClient:一个内存缓存客户端实现。这种缓存实现仅在进程的生命周期内有效。值得注意的是,内存缓存客户端可以通过MaxItems属性缓存最后X项。我们在Exceptionless中使用它,仅保留最后250个解析的geoip结果
  2. HybridCacheClient:这种缓存实现同时使用ICacheClientInMemoryCacheClient,并使用IMessageBus在进程间保持缓存同步。这可以带来巨大性能提升,因为如果您在本地缓存中找到了项目,您可以节省序列化操作和远程缓存调用。
  3. RedisCacheClient:一个Redis缓存客户端实现。
  4. RedisHybridCacheClient:使用 RedisCacheClient 作为 ICacheClient 和使用 RedisMessageBus 作为 IMessageBusHybridCacheClient 实现。
  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 Storage 队列实现。
  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. 工作项作业:工作项作业将在工作池中与其他工作项作业一起运行。此类作业非常适合那些不经常但应作为作业处理的事情(例如:删除有众多子项的实体)。它将在您在消息总线上发布消息时触发。作业必须从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:内存中的度量 implantation。
  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-browser 已计算。 net8.0-android 已计算。 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 Framework 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 86 3/27/2024
10.7.0 669 1/5/2024
10.6.1 752 6/23/2023
10.6.0 1,166 1/1/2023
10.5.0 480 5/18/2022
10.4.0 3,131 3/7/2022
10.3.1 457 1/20/2022
10.3.0 432 1/20/2022
10.2.5 314 12/7/2021
10.2.4 705 12/3/2021
10.2.3 282 11/22/2021
10.2.2 580 9/23/2021
10.2.1 447 7/19/2021
10.2.0 337 7/8/2021
10.1.4 1,383 6/16/2021
10.1.3 344 4/23/2021
10.1.2 353 4/23/2021
10.1.1 355 4/15/2021
10.1.0 334 4/13/2021
10.0.2 371 1/20/2021
10.0.1 499 11/2/2020
10.0.0 522 9/16/2020
10.0.0-beta9 299 8/25/2020
10.0.0-beta8 285 8/3/2020
10.0.0-beta7 338 7/29/2020
10.0.0-beta6 350 7/7/2020
10.0.0-beta5 488 6/20/2020
10.0.0-beta3 297 6/14/2020
10.0.0-beta2 388 6/6/2020
10.0.0-beta10 346 9/15/2020
10.0.0-beta1 330 5/26/2020
10.0.0-alpha3 320 5/5/2020
10.0.0-alpha2 293 4/27/2020
10.0.0-alpha1 295 4/25/2020
9.1.1 4,082 4/28/2020
9.1.0 444 4/28/2020