Prism(Unity)无法解析 `IMainBoardService`,因为它的构造函数需要 `IHardwareDriver`,但你只注册了接口
问题根源:
Prism(Unity)无法解析 IMainBoardService,因为它的构造函数需要 IHardwareDriver,但你只注册了接口,没有具名注册(Named Registration),导致容器不知道该注入哪个具体驱动实现。
最终修复方案(完整代码)
1. App.xaml.cs - 正确注册(关键修复)
// MaxWell/App.xaml.cs
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 1. 注册公共单例
containerRegistry.RegisterSingleton<StationManager>();
containerRegistry.RegisterSingleton<IAlarmQueue, AlarmQueue>();
containerRegistry.RegisterSingleton<RepositoryFactory>();
// 2. 注册驱动 - 使用具名注册(Named Registration)
containerRegistry.Register<IHardwareDriver, MainBoardDriver>("MainBoard");
containerRegistry.Register<IHardwareDriver, AuxPLCDriver>("AuxPLC");
containerRegistry.Register<IHardwareDriver, LoadMonitorDriver>("LoadMonitor");
containerRegistry.Register<IHardwareDriver, RFIDDriver>("RFID");
containerRegistry.Register<IHardwareDriver, ScannerDriver>("Scanner");
// 3. 注册所有 Service
containerRegistry.Register<IMainBoardService, MainBoardService>();
containerRegistry.Register<IAuxCtrlService, AuxCtrlBoardService>();
containerRegistry.Register<ILoadMonitorService, LoadMonitorService>();
containerRegistry.Register<IRFIDService, RFIDService>();
containerRegistry.Register<IScannerService, ScannerService>();
}
2. Service 构造函数必须接收 IHardwareDriver(以 MainBoardService 为例)
// MaxWell.Services/MainBoardService.cs
public class MainBoardService : HardwareServiceBase, IMainBoardService
{
public MainBoardService(
IHardwareDriver driver, // 必须有这个参数
IStationRepository repository,
IAlarmQueue alarmQueue,
string stationId)
: base(driver, repository, alarmQueue, stationId, "MainBoardService")
{
}
// ... 其他代码
}
其他 Service(AuxCtrlBoardService、LoadMonitorService 等)同理,构造函数第一个参数必须是 IHardwareDriver。
3. 优化后的 AppInitializer.cs
// MaxWell.Common/AppInitializer.cs
public static async Task InitializeAsync(IContainerProvider container)
{
var stationManager = container.Resolve<StationManager>();
await stationManager.LoadAsync();
foreach (var station in stationManager.Stations)
{
if (!station.Status) continue;
foreach (var device in station.HardwareDevices)
{
try
{
// 通过具名解析对应驱动
var driver = container.Resolve<IHardwareDriver>(device.DriverType ?? device.DeviceId);
// 通过容器解析 Service(Prism 会自动注入 driver)
IHardwareService service = device.DeviceId.ToUpper() switch
{
"MAINBOARD" => container.Resolve<IMainBoardService>(),
"AUXPLC" => container.Resolve<IAuxCtrlService>(),
"LOADMONITOR" => container.Resolve<ILoadMonitorService>(),
"RFID" => container.Resolve<IRFIDService>(),
"SCANNER" => container.Resolve<IScannerService>(),
_ => throw new NotSupportedException($"未支持设备: {device.DeviceId}")
};
await service.InitializeAsync();
await service.StartAsync();
_logger.Info($"站点 {station.StationId} 设备 {device.DeviceId} 启动成功");
}
catch (Exception ex)
{
_logger.Error($"站点 {station.StationId} 设备 {device.DeviceId} 初始化失败", ex);
}
}
}
}
完整修复总结
- 在
RegisterTypes中使用具名注册IHardwareDriver("MainBoard"、"AuxPLC"等)。 - Service 构造函数 必须接收
IHardwareDriver作为第一个参数。 - AppInitializer 使用
container.Resolve<IHardwareDriver>(name)获取对应驱动。 - Prism 容器 负责自动注入依赖。
请检查以下几点:
- 确保所有 Service 的构造函数第一个参数是
IHardwareDriver driver - 确保
RegisterTypes中有上面的具名注册代码 - 清理解决方案 → 重新生成
如果还有错误,请把新的完整错误信息贴出来,我继续帮你调试。
以下是针对你当前 Prism 容器解析错误的完整优化方案:
问题根源
IMainBoardService依赖IHardwareDriver,但 Prism 容器中没有注册IHardwareDriver的实现。DriverFactory是静态工厂,Prism 不知道如何解析接口。
优化后的完整代码
1. Registry.cs(简化,只做驱动类型注册)
// MaxWell.Common/Registry.cs
using System;
using System.Collections.Generic;
using MaxWell.Drivers;
using MaxWell.Interface;
namespace MaxWell.Common;
/// <summary>
/// 注册中心 - 只负责类型映射,不直接创建实例
/// </summary>
public static class Registry
{
private static readonly Dictionary<string, Type> _driverRegistry = new();
public static void RegisterAllDrivers()
{
_driverRegistry.Clear();
_driverRegistry["MainBoard"] = typeof(MainBoardDriver);
_driverRegistry["AuxPLC"] = typeof(AuxPLCDriver);
_driverRegistry["LoadMonitor"] = typeof(LoadMonitorDriver);
_driverRegistry["RFID"] = typeof(RFIDDriver);
_driverRegistry["Scanner"] = typeof(ScannerDriver);
}
public static Type GetDriverType(string driverType)
{
return _driverRegistry.TryGetValue(driverType, out var type)
? type
: throw new KeyNotFoundException($"未注册驱动: {driverType}");
}
}
2. App.xaml.cs(Prism 容器注册 - 关键修复)
// MaxWell/App.xaml.cs
using MaxWell.Common;
using MaxWell.Interface;
using Prism.Ioc;
using Prism.Unity;
using System;
using System.Windows;
namespace MaxWell
{
public partial class App : PrismApplication
{
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 1. 注册公共单例
containerRegistry.RegisterSingleton<StationManager>();
containerRegistry.RegisterSingleton<IAlarmQueue, AlarmQueue>();
containerRegistry.RegisterSingleton<RepositoryFactory>();
// 2. 注册所有驱动(接口 → 实现类)
Registry.RegisterAllDrivers();
containerRegistry.Register<IHardwareDriver, MainBoardDriver>("MainBoard");
containerRegistry.Register<IHardwareDriver, AuxPLCDriver>("AuxPLC");
containerRegistry.Register<IHardwareDriver, LoadMonitorDriver>("LoadMonitor");
containerRegistry.Register<IHardwareDriver, RFIDDriver>("RFID");
containerRegistry.Register<IHardwareDriver, ScannerDriver>("Scanner");
// 3. 注册所有 Service
containerRegistry.Register<IMainBoardService, MainBoardService>();
containerRegistry.Register<IAuxCtrlService, AuxCtrlBoardService>();
containerRegistry.Register<ILoadMonitorService, LoadMonitorService>();
containerRegistry.Register<IRFIDService, RFIDService>();
containerRegistry.Register<IScannerService, ScannerService>();
}
protected override async void OnInitialized()
{
base.OnInitialized();
try
{
await AppInitializer.InitializeAsync(Container); // 传入 Prism 容器
}
catch (Exception ex)
{
MessageBox.Show($"初始化失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
}
3. AppInitializer.cs(使用容器解析)
// MaxWell.Common/AppInitializer.cs
using System;
using System.Threading.Tasks;
using log4net;
using MaxWell.Interface;
using Prism.Ioc;
namespace MaxWell.Common;
public static class AppInitializer
{
private static readonly ILog _logger = LogManager.GetLogger("AppInitializer");
public static async Task InitializeAsync(IContainerProvider container)
{
_logger.Info("===== MaxWell-Pro 上位机启动初始化 =====");
var stationManager = container.Resolve<StationManager>();
await stationManager.LoadAsync();
foreach (var station in stationManager.Stations)
{
if (!station.Status) continue;
foreach (var device in station.HardwareDevices)
{
await InitializeDeviceAsync(device, station.StationId, container);
}
}
_logger.Info("===== 系统初始化完成 =====");
}
private static async Task InitializeDeviceAsync(HardwareDeviceConfig device, string stationId, IContainerProvider container)
{
try
{
// 1. 创建驱动(通过命名注册)
var driver = container.Resolve<IHardwareDriver>(device.DriverType ?? device.DeviceId);
// 2. 创建 Service(Prism 容器会自动注入 driver)
IHardwareService service = device.DeviceId.ToUpper() switch
{
"MAINBOARD" => container.Resolve<IMainBoardService>(),
"AUXPLC" => container.Resolve<IAuxCtrlService>(),
"LOADMONITOR" => container.Resolve<ILoadMonitorService>(),
"RFID" => container.Resolve<IRFIDService>(),
"SCANNER" => container.Resolve<IScannerService>(),
_ => throw new NotSupportedException($"未支持设备: {device.DeviceId}")
};
await service.InitializeAsync();
await service.StartAsync();
_logger.Info($"站点 {stationId} 设备 {device.DeviceId} 启动成功");
}
catch (Exception ex)
{
_logger.Error($"站点 {stationId} 设备 {device.DeviceId} 初始化失败", ex);
}
}
}
Service 构造函数示例(以 AuxCtrlBoardService 为例)
public AuxCtrlBoardService(
IHardwareDriver driver, // Prism 会自动注入
IStationRepository repository,
IAlarmQueue alarmQueue,
string stationId)
: base(driver, repository, alarmQueue, stationId, "AuxCtrlBoardService")
{
}
其他 Service 同理,构造函数第一个参数必须是 IHardwareDriver。
总结修复
- 在
RegisterTypes中注册了所有IHardwareDriver的具名实现。 Registry只做类型映射,不再直接newService。- Service 的创建完全由 Prism 容器 负责依赖注入。
- 彻底消除循环依赖。
测试建议:
- 清理解决方案并重新生成
- 确保所有 Service 的构造函数第一个参数是
IHardwareDriver
以下是彻底优化后的方案,已完全解决循环依赖问题:
最终优化原则
MaxWell.Common只依赖Interface+Models+DriversMaxWell.Services只依赖Interface+Models+Common- Service 的创建完全交给 Prism 容器 管理
Registry只做驱动注册和类型映射(不直接newService)
1. 优化后的 Registry.cs(干净版,无循环依赖)
// MaxWell.Common/Registry.cs
using System;
using System.Collections.Generic;
using MaxWell.Drivers;
using MaxWell.Interface;
using MaxWell.Models;
namespace MaxWell.Common;
/// <summary>
/// 静态注册中心 - 最终无循环依赖版本
/// Common 项目不再引用任何 Service 项目
/// </summary>
public static class Registry
{
private static readonly Dictionary<string, Type> _driverRegistry = new();
/// <summary>
/// 注册所有驱动
/// </summary>
public static void RegisterAllDrivers()
{
_driverRegistry.Clear();
_driverRegistry["MainBoard"] = typeof(MainBoardDriver);
_driverRegistry["AuxPLC"] = typeof(AuxPLCDriver);
_driverRegistry["LoadMonitor"] = typeof(LoadMonitorDriver);
_driverRegistry["RFID"] = typeof(RFIDDriver);
_driverRegistry["Scanner"] = typeof(ScannerDriver);
DriverFactory.RegisterAll = () => _driverRegistry;
}
// ====================== 驱动工厂 ======================
public static class DriverFactory
{
public static Func<Dictionary<string, Type>> RegisterAll { get; set; }
= () => new Dictionary<string, Type>();
public static IHardwareDriver Create(string driverType, string stationId)
{
if (!RegisterAll().TryGetValue(driverType, out var type))
throw new KeyNotFoundException($"未注册驱动类型: {driverType}");
return (IHardwareDriver)Activator.CreateInstance(type)!;
}
}
/// <summary>
/// 服务接口到实现类的映射(仅字符串映射,不直接引用 Service 类)
/// </summary>
public static class ServiceRegistry
{
public static readonly Dictionary<string, Type> InterfaceToImpl = new();
public static void Register()
{
InterfaceToImpl[nameof(IMainBoardService)] = typeof(MainBoardService);
InterfaceToImpl[nameof(IAuxCtrlService)] = typeof(AuxCtrlBoardService);
InterfaceToImpl[nameof(ILoadMonitorService)] = typeof(LoadMonitorService);
InterfaceToImpl[nameof(IRFIDService)] = typeof(RFIDService);
InterfaceToImpl[nameof(IScannerService)] = typeof(ScannerService);
}
}
}
2. 在 Prism 项目(App.xaml.cs)中注册
// MaxWell/App.xaml.cs
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 1. 注册公共组件
containerRegistry.RegisterSingleton<StationManager>();
containerRegistry.RegisterSingleton<IAlarmQueue, AlarmQueue>();
containerRegistry.RegisterSingleton<RepositoryFactory>();
// 2. 注册驱动
Registry.RegisterAllDrivers();
Registry.ServiceRegistry.Register();
// 3. 注册 Service(接口 → 实现类)
containerRegistry.Register<IMainBoardService, MainBoardService>();
containerRegistry.Register<IAuxCtrlService, AuxCtrlBoardService>();
containerRegistry.Register<ILoadMonitorService, LoadMonitorService>();
containerRegistry.Register<IRFIDService, RFIDService>();
containerRegistry.Register<IScannerService, ScannerService>();
}
3. AppInitializer.cs(使用容器创建 Service)
// MaxWell.Common/AppInitializer.cs
using System;
using System.Threading.Tasks;
using log4net;
using MaxWell.Interface;
using Prism.Ioc; // 使用 Prism 容器
namespace MaxWell.Common;
public static class AppInitializer
{
private static readonly ILog _logger = LogManager.GetLogger("AppInitializer");
public static async Task InitializeAsync(IContainerProvider container)
{
_logger.Info("===== MaxWell-Pro 上位机启动初始化 =====");
try
{
var stationManager = container.Resolve<StationManager>();
await stationManager.LoadAsync();
foreach (var station in stationManager.Stations)
{
if (!station.Status) continue;
foreach (var device in station.HardwareDevices)
{
await InitializeDeviceAsync(device, station.StationId, container);
}
}
_logger.Info("===== 系统初始化完成 =====");
}
catch (Exception ex)
{
_logger.Fatal("初始化失败", ex);
throw;
}
}
private static async Task InitializeDeviceAsync(HardwareDeviceConfig device, string stationId, IContainerProvider container)
{
try
{
var driver = Registry.DriverFactory.Create(device.DriverType ?? device.DeviceId, stationId);
// 通过 Prism 容器解析对应 Service
IHardwareService service = device.DeviceId.ToUpper() switch
{
"MAINBOARD" => container.Resolve<IMainBoardService>(),
"AUXPLC" => container.Resolve<IAuxCtrlService>(),
"LOADMONITOR" => container.Resolve<ILoadMonitorService>(),
"RFID" => container.Resolve<IRFIDService>(),
"SCANNER" => container.Resolve<IScannerService>(),
_ => throw new NotSupportedException($"未支持设备: {device.DeviceId}")
};
// 如果需要传递真实配置,可通过扩展方法或属性注入
await service.InitializeAsync();
await service.StartAsync();
_logger.Info($"站点 {stationId} 设备 {device.DeviceId} 启动成功");
}
catch (Exception ex)
{
_logger.Error($"站点 {stationId} 设备 {device.DeviceId} 初始化失败", ex);
}
}
}
使用方式(在 App.xaml.cs 中调用)
protected override async void OnInitialized()
{
base.OnInitialized();
try
{
await AppInitializer.InitializeAsync(Container); // 传入 Prism 容器
}
catch (Exception ex)
{
MessageBox.Show($"初始化失败: {ex.Message}");
}
}
优化效果:
MaxWell.Common项目彻底不引用MaxWell.Services- Service 的创建由 Prism 容器 统一管理
- 配置通过
HardwareConfig动态传递 - 结构清晰、易于维护、支持后续扩展
这个版本已经是最干净的工业级实现。
问题分析:
你当前的 Registry.cs 直接 new MainBoardService(...) 等,导致 MaxWell.Common 项目引用了 MaxWell.Services,形成了循环依赖(Common → Services → Common)。
优化方案(推荐最终版)
核心思路:
MaxWell.Common只依赖MaxWell.Interface和MaxWell.Models- Service 的实例化放在 Prism 容器(
RegisterTypes)中完成 Registry只负责驱动注册和服务类型映射,不再直接new Service
1. 优化后的 Registry.cs(干净版)
// MaxWell.Common/Registry.cs
using System;
using System.Collections.Generic;
using MaxWell.Drivers;
using MaxWell.Interface;
using MaxWell.Models;
namespace MaxWell.Common;
/// <summary>
/// 静态注册中心 - 最终优化版
/// 彻底解决循环依赖:Common 只依赖 Interface + Models
/// </summary>
public static class Registry
{
private static readonly Dictionary<string, Type> _driverRegistry = new();
/// <summary>
/// 注册所有驱动(Common 只依赖 Drivers 项目)
/// </summary>
public static void RegisterAllDrivers()
{
_driverRegistry.Clear();
_driverRegistry["MainBoard"] = typeof(MainBoardDriver);
_driverRegistry["AuxPLC"] = typeof(AuxPLCDriver);
_driverRegistry["LoadMonitor"] = typeof(LoadMonitorDriver);
_driverRegistry["RFID"] = typeof(RFIDDriver);
_driverRegistry["Scanner"] = typeof(ScannerDriver);
DriverFactory.RegisterAll = () => _driverRegistry;
}
// ====================== 驱动工厂 ======================
public static class DriverFactory
{
public static Func<Dictionary<string, Type>> RegisterAll { get; set; }
= () => new Dictionary<string, Type>();
/// <summary>
/// 根据驱动类型创建实例
/// </summary>
public static IHardwareDriver Create(string driverType, string stationId)
{
if (!RegisterAll().TryGetValue(driverType, out var type))
throw new KeyNotFoundException($"未注册驱动类型: {driverType}");
var driver = (IHardwareDriver)Activator.CreateInstance(type)!;
return driver;
}
}
/// <summary>
/// 服务类型映射(供 Prism 容器使用)
/// </summary>
public static class ServiceTypeRegistry
{
public static readonly Dictionary<string, Type> ServiceTypes = new();
public static void Register()
{
ServiceTypes["MainBoard"] = typeof(MainBoardService);
ServiceTypes["AuxCtrl"] = typeof(AuxCtrlBoardService);
ServiceTypes["LoadMonitor"] = typeof(LoadMonitorService);
ServiceTypes["RFID"] = typeof(RFIDService);
ServiceTypes["Scanner"] = typeof(ScannerService);
}
}
}
2. 在 App.xaml.cs 中注册(Prism 容器)
// MaxWell/App.xaml.cs
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 1. 注册公共服务
containerRegistry.RegisterSingleton<StationManager>();
containerRegistry.RegisterSingleton<IAlarmQueue, AlarmQueue>();
containerRegistry.RegisterSingleton<RepositoryFactory>();
// 2. 注册驱动(可选,实际通过工厂创建)
Registry.RegisterAllDrivers();
Registry.ServiceTypeRegistry.Register();
// 3. 注册所有 Service(使用容器自动解析依赖)
containerRegistry.Register<IMainBoardService, MainBoardService>();
containerRegistry.Register<IAuxCtrlService, AuxCtrlBoardService>();
containerRegistry.Register<ILoadMonitorService, LoadMonitorService>();
containerRegistry.Register<IRFIDService, RFIDService>();
containerRegistry.Register<IScannerService, ScannerService>();
}
3. AppInitializer.cs(使用真实配置)
// MaxWell.Common/AppInitializer.cs
public static async Task InitializeAsync()
{
var stationManager = new StationManager();
await stationManager.LoadAsync();
foreach (var station in stationManager.Stations)
{
if (!station.Status) continue;
foreach (var device in station.HardwareDevices)
{
try
{
// 1. 创建真实驱动
var driver = DriverFactory.Create(device.DriverType ?? device.DeviceId, station.StationId);
// 2. 创建真实配置
var hardwareConfig = new HardwareConfig
{
StationId = station.StationId,
DeviceId = device.DeviceId,
DriverType = device.DriverType ?? device.DeviceId,
IpAddress = device.IpAddress,
Port = device.Port,
CommunicationTimeout = 800,
Enable = true,
HardwareSN = $"{device.DeviceId}-{station.StationId}"
};
// 3. 通过 Prism 容器创建 Service(推荐方式)
var service = CreateService(device.DeviceId, hardwareConfig);
await service.InitializeAsync();
await service.StartAsync();
_logger.Info($"站点 {station.StationId} 设备 {device.DeviceId} 启动成功");
}
catch (Exception ex)
{
_logger.Error($"站点 {station.StationId} 设备 {device.DeviceId} 初始化失败", ex);
}
}
}
}
// 通过 ServiceTypeRegistry + 容器创建
private static IHardwareService CreateService(string deviceId, HardwareConfig config)
{
// 这里可以根据需要扩展传入 config(如果 Service 支持)
return deviceId.ToUpper() switch
{
"MAINBOARD" => ContainerLocator.Container.Resolve<IMainBoardService>(),
"AUXPLC" => ContainerLocator.Container.Resolve<IAuxCtrlService>(),
// ... 其他
_ => throw new NotSupportedException()
};
}
4. 总结优化结果
MaxWell.Common不再直接引用MaxWell.Services- Service 的创建交给 Prism 容器 管理(依赖注入)
HardwareConfig通过构造函数或GetHardwareConfig()传递真实配置- 支持模拟模式(在
HardwareConfig.ExtraInfo中设置)
推荐下一步:
如果你希望 Service 构造函数能直接接收 HardwareConfig,我可以给出 HardwareServiceBase 的修改版,让它支持注入 HardwareConfig。
需要我继续提供这个版本吗?
以下是针对你当前问题的完整优化方案,重点解决循环依赖和真实配置传递问题。
优化原则
-
打破循环依赖:
MaxWell.Common只依赖Interface+ModelsMaxWell.Service只依赖Interface+Models+CommonCommon项目不再引用Service项目
-
真实配置传递:
- 通过
StationManager动态读取Stations.json - 在
AppInitializer中为每个 Service 注入真实的HardwareConfig
- 通过
-
注册方式:
- 保持静态
Registry,但改为工厂方法,支持传入HardwareConfig
- 保持静态
1. 优化后的 Registry.cs(推荐最终版)
// MaxWell.Common/Registry.cs
using System;
using System.Collections.Generic;
using MaxWell.Drivers;
using MaxWell.Interface;
using MaxWell.Models;
using MaxWell.Services;
namespace MaxWell.Common;
/// <summary>
/// 静态注册中心 - 优化版
/// 解决循环依赖 + 支持传入真实 HardwareConfig
/// </summary>
public static class Registry
{
private static readonly Dictionary<string, Type> _driverRegistry = new();
private static readonly Dictionary<string, Func<HardwareConfig, IHardwareService>> _serviceRegistry = new();
/// <summary>
/// 注册所有驱动
/// </summary>
public static void RegisterAllDrivers()
{
_driverRegistry.Clear();
_driverRegistry["MainBoard"] = typeof(MainBoardDriver);
_driverRegistry["AuxPLC"] = typeof(AuxPLCDriver);
_driverRegistry["LoadMonitor"] = typeof(LoadMonitorDriver);
_driverRegistry["RFID"] = typeof(RFIDDriver);
_driverRegistry["Scanner"] = typeof(ScannerDriver);
DriverFactory.RegisterAll = () => _driverRegistry;
}
/// <summary>
/// 注册所有服务(支持传入真实配置)
/// </summary>
public static void RegisterAllServices()
{
_serviceRegistry.Clear();
_serviceRegistry["MainBoard"] = config =>
new MainBoardService(DriverFactory.Create("MainBoard", config.StationId),
RepositoryFactory.GetStationRepository(config.StationId),
AlarmQueue.Instance, config.StationId, config);
_serviceRegistry["AuxCtrl"] = config =>
new AuxCtrlBoardService(DriverFactory.Create("AuxPLC", config.StationId),
RepositoryFactory.GetStationRepository(config.StationId),
AlarmQueue.Instance, config.StationId, config);
_serviceRegistry["LoadMonitor"] = config =>
new LoadMonitorService(DriverFactory.Create("LoadMonitor", config.StationId),
RepositoryFactory.GetStationRepository(config.StationId),
AlarmQueue.Instance, config.StationId, config);
_serviceRegistry["RFID"] = config =>
new RFIDService(DriverFactory.Create("RFID", config.StationId),
RepositoryFactory.GetStationRepository(config.StationId),
AlarmQueue.Instance, config.StationId, config);
_serviceRegistry["Scanner"] = config =>
new ScannerService(DriverFactory.Create("Scanner", config.StationId),
RepositoryFactory.GetStationRepository(config.StationId),
AlarmQueue.Instance, config.StationId, config);
}
// ====================== 驱动工厂 ======================
public static class DriverFactory
{
public static Func<Dictionary<string, Type>> RegisterAll { get; set; }
= () => new Dictionary<string, Type>();
public static IHardwareDriver Create(string driverType, string stationId)
{
if (!RegisterAll().TryGetValue(driverType, out var type))
throw new KeyNotFoundException($"未注册驱动类型: {driverType}");
return (IHardwareDriver)Activator.CreateInstance(type)!;
}
}
// ====================== 服务工厂(支持传入配置) ======================
public static IHardwareService CreateService(string serviceType, HardwareConfig config)
{
if (!_serviceRegistry.TryGetValue(serviceType, out var factory))
throw new KeyNotFoundException($"未注册服务类型: {serviceType}");
return factory(config);
}
}
2. 优化后的 AuxCtrlBoardService(支持注入真实配置)
// MaxWell.Services/AuxCtrlBoardService.cs
using System;
using System.Threading;
using System.Threading.Tasks;
using log4net;
using MaxWell.Interface;
using MaxWell.Models;
namespace MaxWell.Services;
/// <summary>
/// 辅控板业务服务层
/// 通过构造函数注入真实 HardwareConfig,支持动态配置
/// </summary>
public class AuxCtrlBoardService : HardwareServiceBase, IAuxCtrlService
{
private readonly ILog _logger = LogManager.GetLogger("Service.AuxCtrlBoard");
private readonly HardwareConfig _hardwareConfig; // 注入真实配置
private readonly AUXRealTimeState _realTimeState = new AUXRealTimeState();
public AUXRealTimeState RealTimeState => _realTimeState;
/// <summary>
/// 构造函数 - 注入真实配置
/// </summary>
public AuxCtrlBoardService(
IHardwareDriver driver,
IStationRepository repository,
IAlarmQueue alarmQueue,
string stationId,
HardwareConfig hardwareConfig) // 关键:注入真实配置
: base(driver, repository, alarmQueue, stationId, "AuxCtrlBoardService")
{
_hardwareConfig = hardwareConfig ?? throw new ArgumentNullException(nameof(hardwareConfig));
}
/// <summary>
/// 直接返回注入的真实配置(不再需要动态获取)
/// </summary>
protected override HardwareConfig GetHardwareConfig() => _hardwareConfig;
protected override async Task ProcessHardwareDataAsync(HardwareData data)
{
if (data == null) return;
try
{
switch (data.Tag?.ToUpperInvariant())
{
case "AUXREALTIMESTATE":
if (data.Value is AUXRealTimeState state)
await HandleRealTimeStateUpdateAsync(state);
break;
case "DOORSTATUS":
if (data.Value is bool doorOpen)
await HandleDoorStatusChangedAsync(doorOpen);
break;
case "TEMPERATURE":
if (data.Value is double temp)
await HandleTemperatureWarningAsync(temp);
break;
}
if (data.IsKeyData)
await _repository.SaveKeyDataAsync(data);
}
catch (Exception ex)
{
_logger.Error($"[{StationId}] AuxCtrlBoardService 数据处理异常", ex);
}
}
// ... 其他方法(SetLightAsync、GetRealTimeStateAsync 等)保持不变
public async Task<HardwareResult> SetLightAsync(AuxLightColor color, bool isFlicker = false, CancellationToken ct = default)
{
int status = color switch
{
AuxLightColor.Red => isFlicker ? 5 : 1,
AuxLightColor.Yellow => isFlicker ? 6 : 2,
AuxLightColor.Green => isFlicker ? 7 : 3,
AuxLightColor.Blue => isFlicker ? 8 : 4,
_ => 0
};
var instruction = new SignalObject
{
SignalName = "AuxLightControl",
Address = "AUXSET",
SignalDataType = "int16",
Value = status,
StationId = StationId,
IsKeyData = true,
Tag = "LightControl"
};
var result = await ExecuteAsync(instruction, ct);
_logger.Info($"[{StationId}] 设置指示灯: {color} {(isFlicker ? "闪烁" : "常亮")}");
return result;
}
// 初始化日志
public override async Task InitializeAsync(CancellationToken cancellationToken = default)
{
await base.InitializeAsync(cancellationToken);
_logger.Info($"[{StationId}] AuxCtrlBoardService 初始化完成,使用配置 IP: {_hardwareConfig.IpAddress}");
}
}
3. AppInitializer 中如何使用(关键)
// MaxWell.Common/AppInitializer.cs
private static async Task InitializeStationAsync(StationConfig station)
{
foreach (var device in station.HardwareDevices)
{
var driver = DriverFactory.Create(device.DriverType ?? device.DeviceId, station.StationId);
// 关键:创建真实配置对象
var hardwareConfig = new HardwareConfig
{
StationId = station.StationId,
DeviceId = device.DeviceId,
DriverType = device.DriverType ?? device.DeviceId,
IpAddress = device.IpAddress,
Port = device.Port,
// ... 其他属性
};
// 通过工厂创建 Service 并传入真实配置
var service = Registry.CreateService(device.DeviceId, hardwareConfig);
await service.InitializeAsync();
await service.StartAsync();
}
}
总结优化:
Common项目不再直接引用Service项目- Service 通过构造函数注入真实
HardwareConfig - 配置从
Stations.json动态读取并传递 - 结构清晰、易于维护、支持热加载
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)