Skip to content

全局上下文

EngineContext 是HMX框架的全局上下文入口,提供服务解析、配置读取、用户会话等核心功能。通过 EngineContext.Current 可以在任何地方访问框架的基础设施。

基本使用

csharp
using Hmx.Core.Runtime;

// 获取全局引擎实例
var engine = EngineContext.Current;

功能一览

功能方法/属性说明
服务解析Resolve<T>()从DI容器解析服务
配置读取GetConfig()读取appsettings.json配置
用户会话User获取当前登录用户信息
本地化Culture设置/获取当前语言文化
模块管理Modules获取已加载的模块列表
选项模式GetOptions<T>()获取配置选项对象
服务检查IsRegistered()检查服务是否已注册
资源管理UnmanagedObjects管理需要释放的资源

服务解析

解析服务

csharp
// 解析泛型服务(常用)
var cache = EngineContext.Current.Resolve<IHmxCache>();
var logger = EngineContext.Current.Resolve<ILogger<MyService>>();

// 解析指定类型的服务
Type serviceType = typeof(IOrderService);
var service = EngineContext.Current.Resolve(serviceType);

在服务基类中使用

csharp
public class HmxAppServiceBase<T>
{
    // 解析日志服务
    protected virtual ILogger<T> Logger
    {
        get { return EngineContext.Current.Resolve<ILogger<T>>(); }
    }

    // 解析缓存服务
    protected virtual IHmxDistributedCache DistributedCache
    {
        get { return EngineContext.Current.Resolve<IHmxDistributedCache>(); }
    }

    protected virtual IHmxCache MemoryCache
    {
        get { return EngineContext.Current.Resolve<IHmxCache>(); }
    }
}

检查服务是否注册

csharp
bool isRegistered = EngineContext.Current.IsRegistered(typeof(IMyService));
if (isRegistered)
{
    var service = EngineContext.Current.Resolve<IMyService>();
}

配置读取

通过扩展方法 GetConfig 快速读取配置:

csharp
// 读取AppSettings配置
var logLevel = EngineContext.Current.GetConfig("AppSettings:loglevel");
var uploadPath = EngineContext.Current.GetConfig("AppSettings:uploadPath");

// 读取连接字符串
var redisConn = EngineContext.Current.GetConfig("ConnectionStrings:redis");
var masterDb = EngineContext.Current.GetConfig("ConnectionStrings:masterdb");

// 读取自定义配置
var nacosNs = EngineContext.Current.GetConfig("AppSettings:nacos_namespace");

配置读取原理

csharp
// 扩展方法内部实现
public static string GetConfig(this IHmxEngine engine, string path)
{
    return engine.Resolve<IConfiguration>().GetSection(path).Get<string>();
}

用户会话

获取当前登录用户的信息:

csharp
var user = EngineContext.Current.User;

if (user != null && user.IsAuthenticated)
{
    string userId = user.UserId;        // 用户ID
    string userName = user.UserName;    // 用户名
    string token = user.Token;          // 认证Token
    UserType userType = user.UserType;  // 用户类型
}

IHmxSession 接口

csharp
public interface IHmxSession
{
    string UserId { get; }
    string UserName { get; }
    string Token { get; }
    bool IsAuthenticated { get; }
    UserType UserType { get; }
}

本地化/多语言

csharp
// 设置当前文化
EngineContext.Current.Culture = "zh-CN";
EngineContext.Current.Culture = "en-US";

// 获取当前文化
string currentCulture = EngineContext.Current.Culture;

选项模式

获取通过 IOptions<T> 注册的配置选项:

csharp
// 获取配置选项
var openAiOptions = EngineContext.Current.GetOptions<OpenAIOptions>();
string modelId = openAiOptions.ModelId;
string endpoint = openAiOptions.Endpoint;

// 获取选项快照(支持热更新)
var snapshotOptions = EngineContext.Current.GetOptionsSnapshot<MyOptions>();

注册选项

csharp
// 在模块中注册选项
services.Configure<OpenAIOptions>(config.GetSection("OpenAI"));

模块管理

csharp
// 获取所有已加载的模块
var modules = EngineContext.Current.Modules;
foreach (var module in modules)
{
    Console.WriteLine($"模块: {module.Name} - {module.Assembly.FullName}");
}

// 加载模块(通常在启动时自动调用)
var manager = EngineContext.Current.LoadModules();

资源管理

管理需要在应用关闭时释放的非托管资源:

csharp
// 添加需要释放的资源
var resource = new SomeUnmanagedResource();
EngineContext.Current.UnmanagedObjects.Add(resource);

// 释放所有非托管资源(应用关闭时调用)
EngineContext.Current.DisposeUnmanagedObjects();

典型使用场景

场景一:在静态方法中访问服务

csharp
public static class Helper
{
    public static string GetUploadPath()
    {
        // 静态方法中无法使用构造函数注入
        // 使用EngineContext解析服务
        var config = EngineContext.Current.Resolve<IConfiguration>();
        return config["AppSettings:uploadPath"];
    }
}

场景二:在过滤器中获取用户信息

csharp
public class PermissionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        var user = EngineContext.Current.User;
        if (user == null || !user.IsAuthenticated)
        {
            context.Result = new UnauthorizedResult();
            return;
        }
        
        // 检查权限...
    }
}

场景三:在后台任务中使用

csharp
public class BackgroundWorker : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            // 后台任务中解析服务
            var cache = EngineContext.Current.Resolve<IHmxCache>();
            var logger = EngineContext.Current.Resolve<ILogger<BackgroundWorker>>();
            
            logger.LogInformation("执行后台任务...");
            
            await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
        }
    }
}

注意事项

  1. 生命周期EngineContext.Current 是全局单例,在整个应用生命周期内有效

  2. 作用域问题:在Web应用中,建议优先使用构造函数注入;Resolve 方法会创建新的作用域

  3. 避免滥用:过度使用 EngineContext.Current.Resolve 会导致服务依赖不透明,建议在无法使用构造函数注入的场景下使用

  4. 空值检查:访问 User 属性前应检查是否为空,未登录时可能为 null

csharp
// ✅ 正确:先检查
if (EngineContext.Current.User != null)
{
    var userId = EngineContext.Current.User.UserId;
}

// ❌ 错误:直接访问可能抛出空引用异常
var userId = EngineContext.Current.User.UserId;

HiMind 工业互联网平台 技术文档