VOOZH about

URL: https://www.nuget.org/packages/Galosys.Foundation.Core/

⇱ NuGet Gallery | Galosys.Foundation.Core 26.5.20.1




Galosys.Foundation.Core 26.5.20.1

dotnet add package Galosys.Foundation.Core --version 26.5.20.1
 
 
NuGet\Install-Package Galosys.Foundation.Core -Version 26.5.20.1
 
 
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Galosys.Foundation.Core" Version="26.5.20.1" />
 
 
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Galosys.Foundation.Core" Version="26.5.20.1" />
 
Directory.Packages.props
<PackageReference Include="Galosys.Foundation.Core" />
 
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Galosys.Foundation.Core --version 26.5.20.1
 
 
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Galosys.Foundation.Core, 26.5.20.1"
 
 
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Galosys.Foundation.Core@26.5.20.1
 
 
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Galosys.Foundation.Core&version=26.5.20.1
 
Install as a Cake Addin
#tool nuget:?package=Galosys.Foundation.Core&version=26.5.20.1
 
Install as a Cake Tool
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

Galosys.Foundation.Core

**成熟�?*: 🟢 稳定 �?生产可用,测试充分,活跃维护

Galosys.Foundation 核心库,提供统一响应模型、DDD 实体基类、扩展方法、安全加密、消息总线、模块化机制等基础能力�?

功能概览

1. 统一响应模型

// 成功响应
var response = UnifiedResponse.Succeed(data, "操作成功");

// 失败响应
var response = UnifiedResponse.Fail("ERROR_CODE", "操作失败");

// 异常响应
var response = UnifiedResponse.Error("ERROR_CODE", exception);

// 处理�?
var response = UnifiedResponse.Processing("PROCESSING_CODE");

2. 实体�?DDD 模式

// 完整实体(含创建者、修改者、软删除�?
public class User : FullEntity<long>
{
 public string Name { get; set; }
}

// 多租户实�?
public class Order : MtMaEntity
{
 public string OrderNo { get; set; }
}

// 基础实体
public class Entity
{
 public IReadOnlyCollection<ApplicationMessage> DomainEvents { get; }
 protected void AddEvent(ApplicationMessage @event) { }
}
实体基类矩阵
Entity (abstract, 领域事件)
 └── Entity<TID> (abstract, [Key, SnowflakeId] Id)
 └── FullEntity<TID> (abstract, IDeletable + ICreator + ILastModifier)
 ├── TenantEntity<TID> : FullEntity<TID>, IMultiTenancy
 ├── AppEntity<TID> : FullEntity<TID>, IMultiApplication
 └── TenantAppEntity<TID> : FullEntity<TID>, IMultiTenancy, IMultiApplication
基类 适用场景 示例
FullEntity<TID> 全局基础数据,不分租户和应用 地区、字典、系统配�?
TenantEntity<TID> 仅分租户 用户、角色、权�?
AppEntity<TID> 仅分应用 菜单、API 接口
TenantAppEntity<TID> 租户 + 应用 租户应用配置
// 仅分租户(用户、角色、权限)
[Table("sys_user")]
public class SysUser : TenantEntity<long> { }

// 仅分应用(菜单、API 接口�?
[Table("sys_menu")]
public class SysMenu : AppEntity<long> { }

// 租户+应用(租户应用配置)
[Table("sys_tenant_app_config")]
public class SysTenantAppConfig : TenantAppEntity<long> { }

// 不分(全局基础数据�?
[Table("sys_region")]
public class SysRegion : FullEntity<long> { }

// 任意实体可按需实现 IConcurrency Mixin
public class SysUser : TenantEntity<long>, IConcurrency
{
 [Timestamp]
 public byte[] RowVersion { get; protected set; } = null!;
}

3. ID 生成�?

// 雪花算法 ID
var id = SnowflakeIdGenerator.Instance.NextId();

// 本地 ID 发生�?
var id = LocalGenerator.NextId();
var couponKey = LocalGenerator.NextCouponKey();
var seqKey = LocalGenerator.NextSeqKey();
var guid = LocalGenerator.NextGuid();

4. 分页

var pageResult = PageOutput.Of(items, total, page, size);

5. 单例模式

// 线程安全的延迟初始化单例
var instance = Singleton<MyService>.GetInstance();

// 使用 Lazy<T> 的单�?
var instance = LazySingleton<MyService>.Instance;

6. 消息订阅/发布

// 发布消息
await publisher.PublishAsync(new UserCreatedEvent(this));

// 订阅消息
public class UserCreatedListener : ApplicationListener<UserCreatedEvent>
{
 public override Task<bool> HandleAsync(UserCreatedEvent e)
 {
 // 处理逻辑
 return Task.FromResult(true);
 }
}

7. 扩展方法

// DateTime 扩展
var lastDay = dt.LastDayInMonth();
var firstDay = dt.FirstDayInMonth();
var isWeekend = dt.IsWeekend();
var workDate = dt.AddWorkDays(3);
var unixMs = dt.ToUnixTimeMilliseconds();
var unixSec = dt.ToUnixTimeSeconds();
var datetime = timestamp.ToDateTime();

// String 扩展
var compressed = "content".ToGZipCompress();
var decompressed = compressed.ToGZipDecompress();

// Object 扩展
var result = obj.GetAsyncResult<Task<string>>();

8. 安全加密

// MD5 加密
var hashed = SecurityTemplate.Md5Encrypt(original);

// DES 加解�?
var encrypted = SecurityTemplate.DesEncrypt(original);
var decrypted = SecurityTemplate.DesDecrypt(encrypted);

// AES 加解�?
var encrypted = SecurityTemplate.AesEncrypt(original, key);
var decrypted = SecurityTemplate.AesDecrypt(encrypted, key);

// AES 对象加解�?
var encrypted = SecurityTemplate.AesEncrypt(sample, key);
var decrypted = SecurityTemplate.AesDecrypt<SampleDto>(encrypted, key);

// RSA 加解�?
var encrypted = SecurityTemplate.RSAEncrypt(original, publicKey);
var decrypted = SecurityTemplate.RSADecrypt(encrypted, privateKey);

// 许可证生成与验证
var license = SecurityTemplate.GenerateLicense(info);
var valid = SecurityTemplate.ValidateLicense(license);

9. 动态代�?

class HttpProxy : ServiceProxy
{
 protected override void Proceed(InvocationContext context)
 {
 var http = context.ServiceProvider.GetRequiredService<IHttpClientFactory>().CreateClient();
 // 自定义调用逻辑
 context.SetReturnValue(http.GetStringAsync("/posts/1"));
 }
}

interface ITypicodeClient
{
 Task<string> ListPostsAsync();
 Task GetPostByIdAsync(int id);
}

var instance = ServiceProxyFactory.CreateProxy(typeof(ITypicodeClient), typeof(HttpProxy), sp) as ITypicodeClient;

10. 进程管理

// 启动进程
var p = new Process().Start("cmd.exe", runAsAdministrator: true);

// 打开浏览�?
p = new Process().Browser("https://example.com");
p = new Process().Browser("https://example.com", "edge.exe");

// 打开资源管理�?
p = new Process().Explore("c://");

// 执行脚本
p = new Process().Script("dotnet.exe", "info");

11. HTTP 客户�?

services.AddHttpClient<IPlaceholderGateway, PlaceholderGateway>(http =>
{
 http.BaseAddress = new Uri("https://jsonplaceholder");
}).AddServiceDiscovery()
 .AddStandardHedgingHandler();

12. 随机数生�?

// 验证�?
var code = Random.Shared.GenerateCaptcha();

// 短信�?
var code = Random.Shared.GenerateSms();

13. 应用程序启动�?

// 实现 IApplicationRunner 接口
public class MyRunner : IApplicationRunner
{
 public int Order => 0;

 public async Task RunAsync(ApplicationArguments args)
 {
 // 启动时执行逻辑
 }
}

14. 插件注册表(PluginRegistry�?

基于策略路由模式的基础设施,根据请求自动匹配对应插件实现。适用于短信网关、支付渠道、物流商等多 provider 场景�?

定义插件

实现 Plugin<TRequest> 接口,该接口要求实现 Supports 方法,SupportsAsync 有默认实现(委托�?Supports):

using Microsoft.Extensions.Plugining;

public class SmsRequest
{
 public string Provider { get; set; }
}

public interface ISmsPlugin : Plugin<SmsRequest>
{
 Task SendAsync(SmsRequest request);
}

internal class AliyunSmsPlugin : ISmsPlugin
{
 public bool Supports(SmsRequest request) => request.Provider == "aliyun";
 public Task SendAsync(SmsRequest request) { /* ... */ }
}

internal class TencentSmsPlugin : ISmsPlugin
{
 public bool Supports(SmsRequest request) => request.Provider == "tencent";
 public Task SendAsync(SmsRequest request) { /* ... */ }
}
最小化配置
// DI 注册(PluginRegistry �?AddCore 中自动注册为 Singleton�?
services.AddTransient<ISmsPlugin, AliyunSmsPlugin>();
services.AddTransient<ISmsPlugin, TencentSmsPlugin>();
基本用法:单匹配

注入 PluginRegistry<TPlugin, TRequest> 并调�?GetPluginFor�?

public class SmsService
{
 private readonly PluginRegistry<ISmsPlugin, SmsRequest> _registry;

 public SmsService(PluginRegistry<ISmsPlugin, SmsRequest> registry) => _registry = registry;

 public async Task SendAsync(SmsRequest request)
 {
 var plugin = _registry.GetPluginFor(request);
 if (plugin == null) throw new InvalidOperationException($"未找�?Provider: {request.Provider}");
 await plugin.SendAsync(request);
 }
}
多匹配:通知广播

GetAllPluginsFor 返回所有匹配的插件,适用于通知、广播场景:

var plugins = _registry.GetAllPluginsFor(request);
await Task.WhenAll(plugins.Select(p => p.SendAsync(request)));
异步匹配

插件可重�?SupportsAsync 实现异步匹配逻辑(如查询数据库判断是否支持)�?

// 异步获取单个匹配插件
var plugin = await _registry.GetPluginForAsync(request);

// 异步获取所有匹配插�?
var plugins = await _registry.GetAllPluginsForAsync(request);
解析模式

通过 PluginResolutionMode 控制插件实例�?DI 生命周期�?

模式 行为 适用场景
PluginResolutionMode.Scoped 创建新的 DI Scope 解析 默认模式,适用�?Scoped 插件
PluginResolutionMode.Singleton 从根容器直接获取 插件�?Singleton 或无需 Scope
// Scoped(默认,无参方法即此模式�?
var plugin = _registry.GetPluginFor(request);
var plugin = _registry.GetPluginFor(request, PluginResolutionMode.Scoped);

// Singleton
var plugin = _registry.GetPluginFor(request, PluginResolutionMode.Singleton);

15. Executor 模板方法

提供命令执行管道,按顺序执行:前置钩�?�?参数校验 �?业务逻辑 �?后置钩子,统一返回 UnifiedResponse�?

最小化配置
// �?IServiceCollection 上调�?AddCola() 注册 Executor + ExtensionPoint 机制
services.AddCola();

指定扫描程序集:

services.AddCola(typeof(OrderCreateCmd).Assembly);
定义命令
using Galosys.Foundation.Core;

public class OrderCreateCmd : CommandBase
{
 public string OrderNo { get; set; }
 public decimal Amount { get; set; }

 public override ValidationResult Validate()
 {
 if (string.IsNullOrEmpty(OrderNo))
 return new ValidationResult("订单号不能为�?);
 return ValidationResult.Success;
 }
}
实现 Executor
using Galosys.Foundation.Core;

public class OrderCreateExecutor : ExecutorBase<OrderCreateCmd>
{
 public OrderCreateExecutor(ILogger<ExecutorBase<OrderCreateCmd>> logger, IServiceProvider serviceProvider)
 : base(logger, serviceProvider) { }

 protected override UnifiedResponse DoExecute(OrderCreateCmd command)
 {
 // 业务逻辑
 return UnifiedResponse.Succeed(new { OrderId = Guid.NewGuid() });
 }

 protected override Task<UnifiedResponse> DoExecuteAsync(OrderCreateCmd command, CancellationToken cancellationToken)
 {
 return Task.FromResult(DoExecute(command));
 }
}
执行管道行为
阶段 方法 说明
前置钩子 OnBeforeExecute 记录日志,可重写
参数校验 command.Validate() 校验失败返回 VALIDATION_ERROR
业务逻辑 DoExecute / DoExecuteAsync 子类必须实现
后置钩子 OnAfterExecute 记录日志,可重写
业务异常 HandleBusinessException 捕获 BizException,返�?BizException.ErrCode
系统异常 HandleSystemException 捕获其他异常,返�?SYSTEM_ERROR

16. 扩展点机制(ExtensionPoint�?

基于阿里巴巴 COLA 架构的扩展点模式,通过 BizScenario(业务身份)路由到不同的扩展点实现,支持多租户、多渠道等业务身份隔离场景�?

定义扩展�?
using Galosys.Foundation.Core;

public interface IPaymentStrategy : IExtensionPoint
{
 Task<PaymentResult> PayAsync(PaymentRequest request);
}
实现扩展�?

使用 [Extension] 特性声明业务身份(命名空间 System.ComponentModel.Annotations):

using Galosys.Foundation.Core;
using System.ComponentModel.Annotations;

[Extension(BizId = "default", UseCase = "default", Scenario = "wechat")]
public class WechatPaymentStrategy : IPaymentStrategy
{
 public Task<PaymentResult> PayAsync(PaymentRequest request)
 {
 return Task.FromResult(new PaymentResult { Message = "微信支付成功" });
 }
}

[Extension(BizId = "default", UseCase = "default", Scenario = "alipay")]
public class AliPaymentStrategy : IPaymentStrategy
{
 public Task<PaymentResult> PayAsync(PaymentRequest request)
 {
 return Task.FromResult(new PaymentResult { Message = "支付宝支付成�? });
 }
}
使用扩展�?
public class PaymentService
{
 private readonly IExtensionExecutor _executor;

 public PaymentService(IExtensionExecutor executor) => _executor = executor;

 public async Task<PaymentResult> Pay(string paymentType, PaymentRequest request)
 {
 var scenario = BizScenario.ValueOf("default", "default", paymentType);
 return await _executor.ExecuteAsync<IPaymentStrategy, PaymentResult>(
 scenario, svc => svc.PayAsync(request));
 }
}
匹配降级策略

查找扩展点时按以下顺序降级:

  1. 精确匹配 �?bizId:useCase:scenario
  2. 场景通配 �?bizId:useCase:*
  3. 用例通配 �?bizId:*:*
  4. *全默�? �?default:default:default

�?[Extension] 特性的实现类自动注册为 BizScenario.Default�?

自定义匹配策�?

通配符匹配逻辑抽象�?IBizScenarioMatcher 接口,可注册自定义实现替换默认的三级降级策略�?

// 默认实现:三级降级(精确 �?场景通配 �?用例通配 �?全局默认�?
services.AddSingleton<IBizScenarioMatcher, DefaultBizScenarioMatcher>();

// 自定义匹配策�?
public class RegexBizScenarioMatcher : IBizScenarioMatcher
{
 public Type? Match(IDictionary<BizScenario, Type> candidates, BizScenario target) { /* ... */ }
 public IEnumerable<Type> MatchAll(IDictionary<BizScenario, Type> candidates, BizScenario target) { /* ... */ }
}
批量扩展点执�?

IExtensionExecutor 支持批量执行所有匹配的扩展点实现:

// ExecuteAll �?依次执行所有匹配扩展点的副作用操作
executor.ExecuteAll<INotifyExtension>(scenario, ext => ext.SendNotification());

// ExecuteAllAsync �?异步依次执行
await executor.ExecuteAllAsync<INotifyExtension>(scenario, ext => ext.SendAsync());

// ReduceAsync �?聚合多个扩展点的返回�?
var totalScore = await executor.ReduceAsync<IScoreStrategy, int>(
 scenario,
 ext => Task.FromResult(ext.Calculate(input)),
 (acc, val) => acc + val,
 seed: 0);

17. 分页查询(PageQuery�?

独立的分页查询基类,不依�?DTO 继承层级,包含分页、排序、分组等属性:

using Galosys.Foundation.Core;

var query = new PageQuery
{
 PageIndex = 2, // 最小值自动保护为 1
 PageSize = 10, // 最小值自动保护为 10
};
query.SetOrderDirection("ASC");

int offset = query.Offset; // (PageIndex - 1) * PageSize = 10
属�? 说明 默认�?
PageIndex 页码(最�?1�? 1
PageSize 每页大小(最�?1�? 10
Offset 偏移量(只读�? (PageIndex-1)*PageSize
OrderDirection 排序方向 "DESC"
OrderBy 排序字段 null
GroupBy 分组字段 null
NeedTotalCount 是否需要总数 true

18. 分层日志通道(ILogChannel�?

**已迁�?*:日志通道、日志实体(AuditLog/LoginLog/RequestLog)、消费者和 Repository 接口已迁�?Galosys.Foundation.Actuator 模块。请参�?Actuator 模块文档�?

19. MessageBus + Outbox 引擎

提供 IMessageBus 统一消息入口(Send + Publish),以及 Transactional Outbox 模式保证业务事务与消息发送的原子性。寄生在 Microsoft.Extensions.MessageBus 命名空间�?

无需 RabbitMQ 即可运行,Core 内置 DefaultMessageBus(Channel 缓冲进程内分发)�?

// �?Core 内置默�?IMessageBus(自动由 AddCore 注册)
// PublishAsync → Channel<(Type, IMessage)> → ConsumeLoopAsync → IMessageHandler<T>
await bus.PublishAsync("order.created", order);

**事务保证(Outbox 模式):** `PendingMsgCol`(AsyncLocal)收集待发送消息,`OutboxSaveChangesInterceptor` 在 `SaveChanges` 时同事务写入 `base_outbox_msg` 表,不再直写 `IOutboxStore`。

```csharp
await _bus.PublishAsync("order.created", order); // → PendingMsgCol
await _db.SaveChangesAsync(); // → 拦截器同事务写入

// 引入 RabbitMQ 后自动覆盖为 RabbitMessageBus // services.AddRabbitMessageBus → TryAddSingleton 不生效,RemoveAll 后重建


**进程内消息处理�?*

实现 `IMessageHandler<T>`(命名空间 `Microsoft.Extensions.MessageBus`):

```csharp
using Microsoft.Extensions.MessageBus;

public class OrderCreatedHandler : IMessageHandler<OrderCreatedEvent>
{
 public Task<bool> HandleAsync(OrderCreatedEvent msg)
 {
 // 处理订单...
 return Task.FromResult(true);
 }
}

// DI 注册
services.AddScoped<IMessageHandler<OrderCreatedEvent>, OrderCreatedHandler>();

*RabbitMQ + Outbox(写 Store �?后台发)�?

services.AddRabbitMessageBus(options => {
 options.EnableOutbox = true;
 options.Outbox.TableName = "base_outbox_msg";
});
services.AddEfCoreOutboxStore<MyDbContext>();

await bus.PublishAsync("order.created", order,
 h => h.With("tenantId", "abc"));

注册链覆盖规则:

引用 IMessageBus IOutboxTransport IOutboxStore
仅 Core DefaultMessageBus LocalOutboxTransport InMemoryOutboxStore
+ RabbitMQ.Client MessageBusOutboxDecoratorRabbitMessageBus RabbitMQTransport 不变
+ RabbitMQ.Client + EF Core 同上 同上 EfCoreOutboxStore

*配置�?

{
 "MessageBus": {
 "EnableOutbox": true,
 "Outbox": {
 "TableName": "base_outbox_msg",
 "BatchSize": 100,
 "PollIntervalMs": 1000,
 "MaxRetryCount": 3,
 "RetentionDays": 7
 }
 }
}

模块化机�?

框架内置完整的模块化系统,自动发现、加载、管理所�?Galosys.Foundation.* 模块�?

Quick Start

最小化配置,一行启用模块化�?

// ASP.NET Core
builder.Host.UseModularization();

// 控制台应�?
var host = Host.CreateDefaultBuilder(args)
 .UseModularization()
 .Locate(); // 构建 Host 并初始化服务定位�?

UseModularization() 会自动扫描所�?Galosys.Foundation.* 程序集,发现实现�?IModule 接口的类,按依赖顺序加载并注册服务�?

模块发现

框架采用两层发现策略�?

  1. 编译�?Source Generator �?在编译时自动生成 [assembly: ModuleManifest] 特性到程序集,运行时直接读取,无需全量反射扫描
  2. *运行时反射兜�? �?若程序集没有清单特性,自动 fallback 到反射扫�?IModule 实现�?

两种方式发现的模块会自动合并去重,完全向后兼容�?

模块元数�?

使用 [ModuleInfo] 标记模块的名称、版本等信息�?

[ModuleInfo("Core", Version = "1.0.0", IsRequired = true)]
internal class CoreModule : IModule
{
 public void ConfigureServices(IServiceCollection services, HostBuilderContext context)
 {
 // 注册模块服务
 }

 public void ConfigureHost(IHostBuilder host)
 {
 // 配置 Host(可选)
 }
}
属�? 类型 默认�? 说明
Name string (必填) 模块名称,用于过滤和查询
Version string "1.0.0" 模块版本�?
IsRequired bool false 标记为必需模块,不会被配置过滤禁用,且参与 Health Check

模块依赖

使用 [DependsOn] 声明模块间依赖关系,框架会自动进行拓扑排序,确保依赖模块先加载:

[DependsOn(typeof(DataModule))]
[ModuleInfo("EntityFrameworkCore")]
internal class EntityFrameworkCoreModule : IModule
{
 public void ConfigureServices(IServiceCollection services, HostBuilderContext context)
 {
 // DataModule 必定在此模块之前加载完成
 }
}

框架会在启动时检测循环依赖,发现循环时抛�?ModuleInitializationException 并终止启动�?

配置过滤

通过 appsettings.json 控制模块的加载行为,适用于不同环境按需裁剪模块�?

{
 "Foundation": {
 "Modules": {
 "Enabled": [], // 白名单,为空时不限制(即允许所有模块加载)
 "Disabled": ["Kafka"] // 黑名单,优先级高�?Enabled(即�?Enabled 包含也会被禁用)
 }
 }
}

*过滤规则�?

  • Enabled 为空数组 �?不限制,加载所有模�?
  • Enabled 非空 �?仅加载列表中的模�?
  • Disabled �?优先级高�?Enabled,名单中的模块不会被加载
  • 标记 IsRequired = true 的模�?不受过滤影响*,始终加�?

*典型场景�?

// 开发环境:禁用消息队列相关模块
{
 "Foundation": {
 "Modules": {
 "Enabled": [],
 "Disabled": ["Kafka", "RabbitMQ"]
 }
 }
}

// 精简部署:仅加载指定模块
{
 "Foundation": {
 "Modules": {
 "Enabled": ["Core", "Data", "EntityFrameworkCore"],
 "Disabled": []
 }
 }
}

运行时查�?

通过注入 IModuleRegistry 查询模块加载状态:

public class MyService
{
 private readonly IModuleRegistry _registry;

 public MyService(IModuleRegistry registry) => _registry = registry;

 public void Check()
 {
 // 获取所有已加载模块
 var loaded = _registry.LoadedModules;

 // 检查指定模块是否已加载(不区分大小写)
 var hasKafka = _registry.IsLoaded("Kafka");
 }
}

ModuleDescriptor 包含以下信息�?

属�? 类型 说明
Name string 模块名称
Version string 模块版本
ModuleType Type 模块实现类型
LoadDuration TimeSpan 加载耗时
Dependencies string[] 依赖的模块名称列�?
IsRequired bool 是否为必需模块

Health Check

框架自动注册模块 Health Check,访�?/health 端点即可查看模块加载状态:

GET /health
�?Healthy: "已加�?12 个模�?

必需模块(IsRequired = true)的加载状态纳入健康检查判定�?

Metrics

框架内置 OpenTelemetry 指标,可通过 Prometheus 等监控系统采集:

Meter: Galosys.Foundation.Modules
Counter: modules.loaded.count // 已加载模块数量,标签: module.name
Histogram: module.load_duration // 模块加载耗时(ms),标�? module.name

DI 上下文服�?

框架内置 ITenantContextIAppContextIUserContext 三个 Singleton 上下文服务,基于 static AsyncLocal<T> 实现请求级隔离,用于在业务层获取当前请求的租户、应用和用户信息�?

设计说明:这三个服务的实现类(TenantContext/AppContext/UserContext)全部使�?static AsyncLocal<T> 存储状态,实例本身无状态。注册为 Singleton 确保可从任何 DI 生命周期(包�?root provider、EF Core OnModelCreating)中安全解析,AsyncLocal 天然按异步上下文隔离,无需担心跨请求污染�?

// DI 注册(在 AddCore 中自动注册)
services.TryAddSingleton<ITenantContext, TenantContext>();
services.TryAddSingleton<IAppContext, AppContext>();
services.TryAddSingleton<IUserContext, UserContext>();
// 使用方式:构造函数注�?
public class MyService
{
 private readonly ITenantContext _tenantContext;
 private readonly IAppContext _appContext;
 private readonly IUserContext _userContext;

 public MyService(ITenantContext tenantContext, IAppContext appContext, IUserContext userContext)
 {
 _tenantContext = tenantContext;
 _appContext = appContext;
 _userContext = userContext;
 }
}

注册服务

// 基础注册(模块化、消息总线、消息发布等) — AddMessageBus() 在 AddCore 内自动调用
services.AddCore();

// 单独注册消息总线(不通过 AddCore 时)
services.AddMessageBus();

// 注册 Executor + ExtensionPoint 机制(扫描入口程序集�?
services.AddCola();

// 指定程序集扫描扩展点
services.AddCola(typeof(MyExtension).Assembly, typeof(OtherExtension).Assembly);

// 消息发布
services.AddApplicationMessagePublisher();

安装

<PackageReference Include="Galosys.Foundation.Core" Version="x.x.x" />

目录结构

Galosys.Foundation.Core/
├── Galosys\Foundation\Core\ # 核心类型(实体、响应、消息等�?
�? ├── ModuleDescriptor.cs # 模块描述�?
�? ├── Executor/ # Executor 模板方法
�? �? ├── ICommand.cs # 命令接口
�? �? ├── CommandBase.cs # 命令基类
�? �? ├── IExecutor.cs # Executor 接口
�? �? ├── ExecutorBase.cs # Executor 基类(模板方法管道)
�? �? ├── ExtensionAwareExecutor.cs # 支持扩展点的 Executor
�? �? └── PageQuery.cs # 分页查询基类
�? └── ExtensionPoint/ # 扩展点机�?
�? ├── BizScenario.cs # 业务身份(record�?
�? ├── IExtensionPoint.cs # 扩展点标记接�?
�? ├── IBizScenarioMatcher.cs # 匹配策略接口
�? ├── DefaultBizScenarioMatcher.cs # 默认三级降级匹配
�? ├── IExtensionRegistry.cs # 扩展点注册器接口
�? ├── ExtensionRegistry.cs # 扩展点注册器实现
�? ├── IExtensionExecutor.cs # 扩展点执行器接口
�? └── ExtensionExecutor.cs # 扩展点执行器实现
├── Microsoft\Extensions\Hosting\ # HostBuilder 扩展
�? └── ModuleHostBuilderExtensions.cs # UseModularization() 入口
├── Microsoft\Extensions\MessageBus\ # 消息总线 + Outbox 引擎
�? ├── IMessageBus.cs # 统一消息入口(Send/Publish)
�? ├── DefaultMessageBus.cs # 进程内默认总线(Channel 缓冲�?
�? ├── LocalOutboxTransport.cs # 本地传输占位
�? ├── IMessageHandler.cs # 消息处理器接口 + IMessage + MessageBase
�? ├── EventBusHeaders.cs # 消息�?
�? ├── IOutboxStore.cs # 存储抽象
�? ├── IOutboxTransport.cs # 传输抽象
�? ├── OutboxMessage.cs # 消息实体
�? ├── OutboxOptions.cs # 配置
�? ├── OutboxDeliveryMode.cs # 投递模式枚�?
�? ├── OutboxMessageStatus.cs # 状态枚�?
�? ├── OutboxPollingStrategy.cs # 轮询策略枚举
�? ├── OutboxBootstrapper.cs # 轮询引擎
�? ├── OutboxCleanupService.cs # 清理服务
�? └── PendingMsgCol.cs # AsyncLocal 消息收集器
�? └── InMemoryOutboxStore.cs # 内存存储(默认�?
├── Microsoft\Extensions\DependencyInjection\ # DI 扩展
�? ├── IModule.cs # 模块接口 + 特性定�?
�? ├── IModuleRegistry.cs # 模块注册表接�?
�? ├── ModuleRegistry.cs # 模块注册表实�?
�? ├── CoreColaServiceCollectionExtensions.cs # AddCola() 注册入口
�? └── OutboxServiceCollectionExtensions.cs # AddOutbox() 注册入口
├── Microsoft\Extensions\Options\ # 配置选项
�? └── ModuleFilterOptions.cs # 模块过滤配置
├── Microsoft\Extensions\Diagnostics\ # 诊断
�? ├── ModuleMetrics.cs # 模块 Metrics
�? └── HealthChecks\ModuleHealthCheck.cs # 模块 Health Check
├── Microsoft\Extensions\DependencyModel\ # 依赖上下文扩�?
�? └── DependencyContextExtensions.cs # 模块发现 + 拓扑排序
├── System\ComponentModel\ # 组件模型扩展
�? ├── Annotations\ExtensionAttribute.cs # 扩展点声明特�?
�? └── DataAnnotations\ValidationResultExtensions.cs # ValidationResult.IsValid()
└── System\ # 扩展方法(按功能模块组织�?
 ├── DateTimeExtensions.cs
 ├── StringExtensions.cs
 ├── ObjectExtensions.cs
 ├── Security\Cryptography\
 ├── Net\Http\
 └── Threading\Tasks\

依赖

  • Microsoft.Extensions.Caching.Abstractions
  • Microsoft.Extensions.Caching.Memory
  • Microsoft.Extensions.DependencyInjection
  • Microsoft.Extensions.DependencyModel
  • Microsoft.Extensions.Diagnostics.HealthChecks
  • Microsoft.Extensions.Hosting
  • Microsoft.Extensions.Http
  • System.Text.Json
  • System.Threading.RateLimiting

Outbox 引擎零新增依赖,复用已有 Microsoft.Extensions.Hosting / DI�?

Product Versions Compatible and additional computed target framework versions.
.NET net8.0 net8.0 is compatible.  net8.0-android net8.0-android was computed.  net8.0-browser net8.0-browser was computed.  net8.0-ios net8.0-ios was computed.  net8.0-maccatalyst net8.0-maccatalyst was computed.  net8.0-macos net8.0-macos was computed.  net8.0-tvos net8.0-tvos was computed.  net8.0-windows net8.0-windows was computed.  net9.0 net9.0 was computed.  net9.0-android net9.0-android was computed.  net9.0-browser net9.0-browser was computed.  net9.0-ios net9.0-ios was computed.  net9.0-maccatalyst net9.0-maccatalyst was computed.  net9.0-macos net9.0-macos was computed.  net9.0-tvos net9.0-tvos was computed.  net9.0-windows net9.0-windows was computed.  net10.0 net10.0 was computed.  net10.0-android net10.0-android was computed.  net10.0-browser net10.0-browser was computed.  net10.0-ios net10.0-ios was computed.  net10.0-maccatalyst net10.0-maccatalyst was computed.  net10.0-macos net10.0-macos was computed.  net10.0-tvos net10.0-tvos was computed.  net10.0-windows net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (125)

Showing the top 5 NuGet packages that depend on Galosys.Foundation.Core:

Package Downloads
Galosys.Foundation.AspNetCore

Galosys.Foundation快速开发库

Galosys.Foundation.AspNetCore.DynamicApi

Galosys.Foundation快速开发库

Galosys.Foundation.Data

Galosys.Foundation快速开发库

Galosys.Foundation.HttpClient

Galosys.Foundation快速开发库

Galosys.Foundation.Redis

Galosys.Foundation快速开发库

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
26.5.20.1 2,407 5/20/2026
26.5.19.1 2,570 5/19/2026
26.5.18.1 2,564 5/18/2026
26.5.15.1 2,563 5/15/2026
26.5.12.3 2,513 5/12/2026
26.5.12.2 2,509 5/12/2026
26.4.27.1-rc1 2,122 4/26/2026
26.4.25.1-rc1 2,111 4/25/2026
26.4.22.2-rc7 2,125 4/22/2026
26.4.22.2-rc6 2,123 4/22/2026
26.4.22.2-rc4 2,123 4/22/2026
26.4.22.2-rc3 1,950 4/22/2026
26.4.19.1-rc1 1,857 4/19/2026
26.4.12.8-rc1 1,918 4/12/2026
26.4.12.7-rc1 1,908 4/12/2026
26.4.12.5-rc1 1,472 4/12/2026
26.1.30.1-rc1 2,298 1/30/2026
26.1.29.1 2,369 1/29/2026
26.1.28.5 2,408 1/28/2026
26.1.28.4 2,346 1/28/2026
Loading failed