VisualizationParserFactory.cs
6.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
using System.Collections.Concurrent;
using System.Reflection;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using Rcs.Domain.Extensions;
using Rcs.Domain.Models.VDA5050;
namespace Rcs.Infrastructure.Mqtt.ParseFactory
{
/// <summary>
/// 可视化解析器工厂实现
/// </summary>
public class VisualizationParserFactory : IVisualizationParserFactory
{
private readonly ILogger<VisualizationParserFactory> _logger;
private readonly ConcurrentDictionary<string, Func<string, Visualization?>> _parsers;
public VisualizationParserFactory(ILogger<VisualizationParserFactory> logger)
{
_logger = logger;
_parsers = new ConcurrentDictionary<string, Func<string, Visualization?>>(StringComparer.OrdinalIgnoreCase);
RegisterDefaultParsers();
}
public Visualization? ParseVisualization(string manufacturer, string payload)
{
try
{
if (string.IsNullOrWhiteSpace(manufacturer))
{
_logger.LogWarning("制造商为空,使用默认VDA5050可视化解析器");
return ParseDefaultVisualization(payload);
}
if (_parsers.TryGetValue(manufacturer, out var parser))
{
return parser(payload);
}
else
{
_logger.LogInformation("未找到制造商 '{Manufacturer}' 的专用解析器,使用默认VDA5050解析器", manufacturer);
return ParseDefaultVisualization(payload);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "解析制造商 '{Manufacturer}' 的可视化信息时发生异常", manufacturer);
return null;
}
}
public void RegisterVisualizationParser(string manufacturer, Func<string, Visualization?> parser)
{
if (string.IsNullOrWhiteSpace(manufacturer))
{
throw new ArgumentException("制造商名不能为空", nameof(manufacturer));
}
if (parser == null)
{
throw new ArgumentNullException(nameof(parser));
}
_parsers.AddOrUpdate(manufacturer, parser, (key, old) => parser);
}
public bool IsManufacturerSupported(string manufacturer)
{
return !string.IsNullOrWhiteSpace(manufacturer) && _parsers.ContainsKey(manufacturer);
}
public IEnumerable<string> GetSupportedManufacturers()
{
return _parsers.Keys.ToList();
}
private void RegisterDefaultParsers()
{
try
{
var coreAssembly = Assembly.GetAssembly(typeof(Visualization));
if (coreAssembly == null)
{
_logger.LogWarning("无法获取HaHRCS.Core.Models.VDA5050 程序集");
return;
}
var visualizationTypes = coreAssembly.GetTypes()
.Where(type => type.IsClass && !type.IsAbstract)
//.Where(type => typeof(VDA5050_Header).IsAssignableFrom(type))
.Where(type =>
{
var protocolInfo = type.GetCustomAttribute<ProtocolInfoAttribute>();
return protocolInfo != null &&
string.Equals(protocolInfo.Topic, nameof(Visualization), StringComparison.OrdinalIgnoreCase);
})
.ToList();
foreach (var type in visualizationTypes)
{
var protocolInfo = type.GetCustomAttribute<ProtocolInfoAttribute>();
if (protocolInfo != null)
{
var parser = CreateParserForType(type);
RegisterVisualizationParser(protocolInfo.Manufacturer, parser);
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "自动注册可视化默认解析器时发生异常");
}
}
private Func<string, Visualization?> CreateParserForType(Type type)
{
return payload =>
{
try
{
var result = JsonSerializer.Deserialize(payload, type);
return result as Visualization;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "解析 {StateType} 类型时发生错误", type.Name);
return null;
}
};
}
private static Visualization? ParseDefaultVisualization(string payload)
{
try
{
return JsonSerializer.Deserialize<Visualization>(payload);
}
catch
{
return null;
}
}
public void RefreshParsers()
{
_logger.LogInformation("开始手动刷新可视化解析器");
_parsers.Clear();
RegisterDefaultParsers();
}
public Dictionary<string, string> GetRegisteredParsersInfo()
{
var result = new Dictionary<string, string>();
try
{
var coreAssembly = Assembly.GetAssembly(typeof(Visualization));
if (coreAssembly != null)
{
var types = coreAssembly.GetTypes()
.Where(type => type.IsClass && !type.IsAbstract)
.Where(type => typeof(VDA5050_Header).IsAssignableFrom(type))
.Where(type =>
{
var protocolInfo = type.GetCustomAttribute<ProtocolInfoAttribute>();
return protocolInfo != null &&
protocolInfo.Topic.Equals(nameof(Visualization), StringComparison.OrdinalIgnoreCase);
});
foreach (var type in types)
{
var protocolInfo = type.GetCustomAttribute<ProtocolInfoAttribute>();
if (protocolInfo != null)
{
result[protocolInfo.Manufacturer] = $"{type.Name} (v{protocolInfo.Version})";
}
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "获取可视化解析器信息时发生异常");
}
return result;
}
}
}