using System; using System.Collections.Generic; namespace TeamAAS.Global { /// /// 插件运行上下文:插件获取平台服务的唯一正规渠道。 /// 目标:插件代码不再直接摸 CameraManager.Instance 等静态单例, /// 而是向宿主要服务 —— 宿主可以把服务放在本进程、独立进程甚至远端(分布式扩展点)。 /// 阶段1:接口先行,宿主适配器后续接入;现有插件行为不受影响。 /// public interface IPluginContext { /// 按类型获取平台服务(相机/机器人/通讯/供料/运动卡管理器等)。未注册返回 null。 T GetService(); /// 按类型对象获取平台服务(非泛型版,供反射场景)。未注册返回 null。 object GetService(Type serviceType); /// 按类型与名称获取设备(如相机名、通讯设备名)。找不到返回 null。 T GetDevice(string deviceName); /// 获取某类设备的全部实例。 IEnumerable GetDevices(); /// 写一条插件日志(level 1~4 详细度,语义与 BasePlugin.Log 一致)。 void Log(string flowName, string nodeName, int level, string message, string category = "Info"); } /// /// 简单服务注册表:宿主启动时注册实例,插件经由 IPluginContext 消费。 /// 线程安全;第一阶段由主程序把现有 Manager 单例注册进来(Adapter 模式,零行为变化)。 /// public sealed class ServiceRegistry : IPluginContext { private static readonly Lazy _default = new Lazy(() => new ServiceRegistry(), isThreadSafe: true); /// 全局默认注册表(宿主未注入自定义实现时使用)。 public static ServiceRegistry Default => _default.Value; private readonly object _sync = new object(); private readonly Dictionary _services = new Dictionary(); /// 注册/替换一个服务实例(按具体类型索引)。 public void Register(T service) { if (service == null) return; lock (_sync) { _services[typeof(T)] = service; } } /// 移除注册。 public void Unregister() { lock (_sync) { _services.Remove(typeof(T)); } } /// public T GetService() { return (T)GetService(typeof(T)); } /// public object GetService(Type serviceType) { if (serviceType == null) return null; lock (_sync) { object svc; return _services.TryGetValue(serviceType, out svc) ? svc : null; } } /// public T GetDevice(string deviceName) { foreach (var device in GetDevices()) { var named = device as TeamAAS.Global.Devices.INamedDevice; if (named == null) continue; // 设备类型未实现 INamedDevice 时无法按名查找 if (string.Equals(named.Name, deviceName, StringComparison.OrdinalIgnoreCase)) return device; } return default(T); } /// public IEnumerable GetDevices() { // IDeviceProvider 带 INamedDevice 约束,此处经反射构造闭合泛型接口后取服务, // 保持 GetDevices 对调用方无约束(注册方负责满足约束)。 var providerType = typeof(TeamAAS.Global.Devices.IDeviceProvider<>).MakeGenericType(typeof(T)); var provider = GetService(providerType); if (provider != null) { var devices = providerType.GetProperty("Devices")?.GetValue(provider) as IEnumerable; if (devices != null) { foreach (var d in devices) yield return d; } yield break; } // 兜底:设备集合本身被当作服务注册(IReadOnlyList 等) var list = GetService>(); if (list != null) { foreach (var d in list) yield return d; } } /// public void Log(string flowName, string nodeName, int level, string message, string category = "Info") { // 阶段1:转发到控制台,宿主接入 PluginLogger 后替换(避免 SDK 反向依赖 TeamAAS.Global) System.Diagnostics.Debug.WriteLine($"[{category}][L{level}][{flowName}/{nodeName}] {message}"); } } }