Foundatio.Utf8Json 10.7.1

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

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

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

实现

入门(开发)

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

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

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

使用Foundatio

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

缓存

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

  1. InMemoryCacheClient:内存中的缓存客户端实现。这种缓存实现只适用于进程的生命周期。值得注意的是,内存中的缓存客户端具有通过MaxItems属性缓存最近X个项目的功能。我们在Exceptionless中使用它,只保留最近解级的250个geoip结果
  2. HybridCacheClient:此缓存实现同时使用ICacheClientInMemoryCacheClient,并通过IMessageBus使得缓存在进程间保持同步。如果物品存在于本地缓存中,这可能会导致性能大幅提升,因为你节省了序列化操作和对外部缓存的调用。
  3. RedisCacheClient:Redis缓存客户端实现。
  4. RedisHybridCacheClientHybridCacheClient的实现,使用RedisCacheClient作为ICacheClientRedisMessageBus作为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 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 服务总线实现。
示例
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 Jobs 运行。
示例
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 Jobs 运行。
示例
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 Jobs 运行。
示例
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 Standard 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 Standard 的信息。

NuGet 包

此包没有被任何 NuGet 包使用。

GitHub 仓库

此包没有被任何流行的 GitHub 仓库使用。

版本 下载 最后更新
10.7.1 95 3/27/2024
10.7.0 180 1/5/2024
10.6.1 188 6/23/2023
10.6.0 295 1/1/2023
10.5.0 439 5/18/2022
10.4.0 477 3/7/2022
10.3.1 449 1/20/2022
10.3.0 427 1/20/2022
10.2.5 291 12/7/2021
10.2.4 677 12/3/2021
10.2.3 273 11/22/2021
10.2.2 322 9/23/2021
10.2.1 344 7/19/2021
10.2.0 368 7/8/2021
10.1.4 392 6/16/2021
10.1.3 350 4/23/2021
10.1.2 336 4/23/2021
10.1.1 354 4/15/2021
10.1.0 348 4/13/2021
10.0.2 376 1/20/2021
10.0.1 486 11/2/2020
10.0.0 935 9/16/2020
10.0.0-beta9 334 8/25/2020
10.0.0-beta8 312 8/3/2020
10.0.0-beta7 349 7/29/2020
10.0.0-beta6 357 7/7/2020
10.0.0-beta5 502 6/20/2020
10.0.0-beta3 320 6/14/2020
10.0.0-beta2 414 6/6/2020
10.0.0-beta10 378 9/15/2020
10.0.0-beta1 362 5/26/2020
10.0.0-alpha3 346 5/5/2020
10.0.0-alpha2 328 4/27/2020
10.0.0-alpha1 336 4/25/2020
9.1.1 522 4/28/2020
9.1.0 484 4/28/2020
9.0.0 519 1/16/2020
8.1.2126 586 8/30/2019
8.1.2123 563 8/27/2019
8.1.2120 557 8/27/2019
8.1.2115 544 8/27/2019
8.1.2109 540 8/26/2019
8.1.2058 562 5/14/2019
8.1.2027 598 4/16/2019
8.0.1965 635 2/24/2019
8.0.1948 605 2/22/2019
7.1.1845 749 11/3/2018
7.1.1841 754 11/3/2018
7.1.1837 679 11/1/2018
7.1.1833 723 11/1/2018
7.0.1831 725 11/1/2018
7.0.1818 683 10/30/2018
7.0.1738 801 9/7/2018
7.0.1706 915 5/9/2018