XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension.NetCore.ServerInteractive

[DLL] Server interaction extension, including user identity verification and querying in conjunction with AutoConfig

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFEExtension.NetCore.ServerInteractive

Add Name property to Request/Response attributes, support AllowMultiple, unify dictionaries, add duplicate path diagnostic

- RequestAttribute and ResponseAttribute: AllowMultiple=true, optional Name property - ClientRequestGenerator: handles multiple attributes per method, generates name entries in dictionaries, generates RequestRouteMap, duplicate path diagnostic XFE0011 - IStandardRequestService/StandardRequestServiceBase: add RequestRouteMap dictionary - XFEClientRequester: remove StandardMultiRequestServiceListDictionary, use RequestRouteMap for URL resolution - XFEClientRequesterBuilder: auto-register all routes with parameterless AddRequest<T>(), remove AddRequest<T>(string) and AddRequest<T>(List<string>) Agent-Logs-Url: https://github.com/XFEstudio/XFEExtension.NetCore.ServerInteractive/sessions/a1e53d1d-33f2-4970-bb42-5a5c1de44993 Co-authored-by: XFEstudio <132526994+XFEstudio@users.noreply.github.com>

1d0c5b6
copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
提交于

代码差异

10 个文件 +226 -109
Modified XFEExtension.NetCore.ServerInteractive.SourceGenerator/AnalyzerReleases.Unshipped.md +2 -1
@@ -12,4 +12,5 @@ XFE0006 | XFEServerInteractive | Error | EntryPointGenerator, [Documentation](ht
12 12 XFE0007 | XFEServerInteractive | Error | ClientRequestGenerator, [Documentation](https://docs.xfegzs.com/View/Errors%2FServerInteractive%2FXFE0007)
13 13 XFE0008 | XFEServerInteractive | Error | ClientRequestGenerator, [Documentation](https://docs.xfegzs.com/View/Errors%2FServerInteractive%2FXFE0008)
14 14 XFE0009 | XFEServerInteractive | Error | ClientRequestGenerator, [Documentation](https://docs.xfegzs.com/View/Errors%2FServerInteractive%2FXFE0009)
15 XFE0010 | XFEServerInteractive | Error | ClientRequestGenerator, [Documentation](https://docs.xfegzs.com/View/Errors%2FServerInteractive%2FXFE0010)
15 XFE0010 | XFEServerInteractive | Error | ClientRequestGenerator, [Documentation](https://docs.xfegzs.com/View/Errors%2FServerInteractive%2FXFE0010)
16 XFE0011 | XFEServerInteractive | Error | ClientRequestGenerator, [Documentation](https://docs.xfegzs.com/View/Errors%2FServerInteractive%2FXFE0011)
Modified XFEExtension.NetCore.ServerInteractive.SourceGenerator/ClientRequestGenerator.cs +176 -47
@@ -53,14 +53,24 @@ public class ClientRequestGenerator : IIncrementalGenerator
53 53 helpLinkUri: "https://docs.xfegzs.com/View/Errors%2FServerInteractive%2FXFE0010",
54 54 isEnabledByDefault: true);
55 55
56 private static readonly DiagnosticDescriptor DuplicatePathRule = new(
57 id: "XFE0011",
58 title: "Request/Response路径重复注册",
59 messageFormat: "路径或名称'{0}'在类'{1}'的[{2}]方法中重复注册",
60 category: "XFEServerInteractive",
61 defaultSeverity: DiagnosticSeverity.Error,
62 helpLinkUri: "https://docs.xfegzs.com/View/Errors%2FServerInteractive%2FXFE0011",
63 isEnabledByDefault: true);
64
56 65 public void Initialize(IncrementalGeneratorInitializationContext context)
57 66 {
58 67 // 找到所有标记了RequestAttribute或ResponseAttribute的方法
59 68 var methodDeclarations = context.SyntaxProvider
60 69 .CreateSyntaxProvider(
61 70 predicate: static (s, _) => IsCandidateMethod(s),
62 transform: static (ctx, _) => GetMethodForGeneration(ctx))
63 .Where(static m => m is not null);
71 transform: static (ctx, _) => GetMethodsForGeneration(ctx))
72 .Where(static m => !m.IsDefault && m.Length > 0)
73 .SelectMany(static (m, _) => m);
64 74
65 75 // 按类分组
66 76 var compilationAndMethods = context.CompilationProvider.Combine(methodDeclarations.Collect());
@@ -72,77 +82,120 @@ public class ClientRequestGenerator : IIncrementalGenerator
72 82
73 83 private static bool IsCandidateMethod(SyntaxNode node) => node is MethodDeclarationSyntax { AttributeLists.Count: > 0 };
74 84
75 private static ClientRequestMethodCandidate? GetMethodForGeneration(GeneratorSyntaxContext context)
85 private static ImmutableArray<ClientRequestMethodCandidate> GetMethodsForGeneration(GeneratorSyntaxContext context)
76 86 {
77 87 var methodDeclaration = (MethodDeclarationSyntax)context.Node;
78 88 var methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodDeclaration);
79 89
80 90 if (methodSymbol is null)
81 return null;
91 return default;
82 92
83 // 检查是否有RequestAttribute或ResponseAttribute
84 var requestAttribute = methodSymbol.GetAttributes()
85 .FirstOrDefault(a => a.AttributeClass?.Name == "RequestAttribute");
86 var responseAttribute = methodSymbol.GetAttributes()
87 .FirstOrDefault(a => a.AttributeClass?.Name == "ResponseAttribute");
93 var attributes = methodSymbol.GetAttributes();
94 var requestAttributes = attributes.Where(a => a.AttributeClass?.Name == "RequestAttribute").ToList();
95 var responseAttributes = attributes.Where(a => a.AttributeClass?.Name == "ResponseAttribute").ToList();
88 96
89 if (requestAttribute is null && responseAttribute is null)
90 return null;
97 if (requestAttributes.Count == 0 && responseAttributes.Count == 0)
98 return default;
91 99
92 var isRequest = requestAttribute is not null;
93 var attribute = isRequest ? requestAttribute! : responseAttribute!;
94 var attributeName = isRequest ? "Request" : "Response";
95
96 // 获取Path参数
97 var path = attribute.ConstructorArguments.FirstOrDefault().Value?.ToString();
98 if (string.IsNullOrEmpty(path))
99 return null;
100
101 // 检查返回类型:必须为object
100 // 共有信息
102 101 var returnType = methodSymbol.ReturnType;
103 102 var isObjectReturn = returnType.SpecialType == SpecialType.System_Object;
104 103
105 // 检查包含类型是否为partial
106 104 var classDeclaration = methodDeclaration.Parent as ClassDeclarationSyntax;
107 105 var isContainingTypePartial = classDeclaration?.Modifiers.Any(SyntaxKind.PartialKeyword) ?? false;
108 106
109 // 获取泛型类型参数和约束
110 107 var typeParameters = classDeclaration?.TypeParameterList?.ToString().Trim() ?? "";
111 108 var typeConstraints = classDeclaration?.ConstraintClauses.ToString().Trim() ?? "";
112 109
113 110 var containingType = methodSymbol.ContainingType;
114 111
115 // 获取位置信息
116 112 var methodLocation = LocationInfo.From(methodDeclaration.GetLocation());
117 113 var classLocation = classDeclaration is not null
118 114 ? LocationInfo.From(classDeclaration.Identifier.GetLocation())
119 115 : methodLocation;
120 116
121 // 收集源文件的using指令
122 117 var compilationUnit = methodDeclaration.SyntaxTree.GetRoot() as CompilationUnitSyntax;
123 118 var usingDirectives = compilationUnit?.Usings
124 119 .Select(u => u.ToString().Trim())
125 120 .ToArray() ?? System.Array.Empty<string>();
126 121
127 return new ClientRequestMethodCandidate(
128 containingType.ContainingNamespace.ToDisplayString(),
129 containingType.Name,
130 methodSymbol.Name,
131 path!,
132 isRequest,
133 isContainingTypePartial,
134 methodSymbol.Parameters.Length,
135 isObjectReturn,
136 returnType.ToDisplayString(),
137 methodLocation,
138 classLocation,
139 typeParameters,
140 typeConstraints,
141 attributeName,
142 usingDirectives);
122 var results = new List<ClientRequestMethodCandidate>();
123
124 // 为每个Request属性创建候选
125 foreach (var attr in requestAttributes)
126 {
127 var path = attr.ConstructorArguments.FirstOrDefault().Value?.ToString();
128 if (string.IsNullOrEmpty(path))
129 continue;
130
131 var name = (string?)null;
132 if (!attr.NamedArguments.IsDefaultOrEmpty)
133 {
134 var nameArg = attr.NamedArguments.FirstOrDefault(kvp => kvp.Key == "Name");
135 if (nameArg.Key is not null)
136 name = nameArg.Value.Value?.ToString();
137 }
138
139 results.Add(new ClientRequestMethodCandidate(
140 containingType.ContainingNamespace.ToDisplayString(),
141 containingType.Name,
142 methodSymbol.Name,
143 path!,
144 name,
145 isRequest: true,
146 isContainingTypePartial,
147 methodSymbol.Parameters.Length,
148 isObjectReturn,
149 returnType.ToDisplayString(),
150 methodLocation,
151 classLocation,
152 typeParameters,
153 typeConstraints,
154 "Request",
155 usingDirectives));
156 }
157
158 // 为每个Response属性创建候选
159 foreach (var attr in responseAttributes)
160 {
161 var path = attr.ConstructorArguments.FirstOrDefault().Value?.ToString();
162 if (string.IsNullOrEmpty(path))
163 continue;
164
165 var name = (string?)null;
166 if (!attr.NamedArguments.IsDefaultOrEmpty)
167 {
168 var nameArg = attr.NamedArguments.FirstOrDefault(kvp => kvp.Key == "Name");
169 if (nameArg.Key is not null)
170 name = nameArg.Value.Value?.ToString();
171 }
172
173 results.Add(new ClientRequestMethodCandidate(
174 containingType.ContainingNamespace.ToDisplayString(),
175 containingType.Name,
176 methodSymbol.Name,
177 path!,
178 name,
179 isRequest: false,
180 isContainingTypePartial,
181 methodSymbol.Parameters.Length,
182 isObjectReturn,
183 returnType.ToDisplayString(),
184 methodLocation,
185 classLocation,
186 typeParameters,
187 typeConstraints,
188 "Response",
189 usingDirectives));
190 }
191
192 if (results.Count == 0)
193 return default;
194
195 return results.ToImmutableArray();
143 196 }
144 197
145 private static void Execute(Compilation compilation, ImmutableArray<ClientRequestMethodCandidate?> methods, SourceProductionContext context)
198 private static void Execute(Compilation compilation, ImmutableArray<ClientRequestMethodCandidate> methods, SourceProductionContext context)
146 199 {
147 200 if (methods.IsDefaultOrEmpty)
148 201 return;
@@ -152,8 +205,6 @@ public class ClientRequestGenerator : IIncrementalGenerator
152 205 // 校验并报告诊断信息
153 206 foreach (var method in methods)
154 207 {
155 if (method is null) continue;
156
157 208 var isValid = true;
158 209
159 210 // 校验:包含类型必须为partial
@@ -219,7 +270,16 @@ public class ClientRequestGenerator : IIncrementalGenerator
219 270 var requestMethods = methodInfos.Where(m => m.IsRequest).ToList();
220 271 var responseMethods = methodInfos.Where(m => !m.IsRequest).ToList();
221 272
222 // 收集所有路径(去重)
273 // 检查重复路径/名称
274 var hasDuplicateError = false;
275
276 hasDuplicateError |= CheckDuplicateKeys(context, requestMethods, className, "Request");
277 hasDuplicateError |= CheckDuplicateKeys(context, responseMethods, className, "Response");
278
279 if (hasDuplicateError)
280 continue;
281
282 // 收集所有路径(去重)— 仅包含实际路由路径
223 283 var allPaths = methodInfos.Select(m => m.Path).Distinct().ToList();
224 284
225 285 // 收集所有using指令(合并去重)
@@ -275,10 +335,14 @@ namespace {namespaceName}
275 335 get => _generatedRequestPoints ??= new Dictionary<string, Func<object>>()
276 336 {{");
277 337
278 // 添加请求方法
338 // 添加请求方法(路径 → 方法 + 名称 → 方法)
279 339 foreach (var method in requestMethods)
280 340 {
281 341 sourceBuilder.AppendLine($" {{ \"{EscapeStringLiteral(method.Path)}\", {method.MethodName} }},");
342 if (!string.IsNullOrEmpty(method.Name))
343 {
344 sourceBuilder.AppendLine($" {{ \"{EscapeStringLiteral(method.Name!)}\", {method.MethodName} }},");
345 }
282 346 }
283 347
284 348 sourceBuilder.AppendLine($@" }};
@@ -291,10 +355,39 @@ namespace {namespaceName}
291 355 get => _generatedResponsePoints ??= new Dictionary<string, Func<object>>()
292 356 {{");
293 357
294 // 添加响应方法
358 // 添加响应方法(路径 → 方法 + 名称 → 方法)
295 359 foreach (var method in responseMethods)
296 360 {
297 361 sourceBuilder.AppendLine($" {{ \"{EscapeStringLiteral(method.Path)}\", {method.MethodName} }},");
362 if (!string.IsNullOrEmpty(method.Name))
363 {
364 sourceBuilder.AppendLine($" {{ \"{EscapeStringLiteral(method.Name!)}\", {method.MethodName} }},");
365 }
366 }
367
368 sourceBuilder.AppendLine($@" }};
369 }}
370
371 private Dictionary<string, string>? _generatedRequestRouteMap;
372 /// <inheritdoc/>
373 public override Dictionary<string, string> RequestRouteMap
374 {{
375 get => _generatedRequestRouteMap ??= new Dictionary<string, string>()
376 {{");
377
378 // 构建路由映射(所有键 → 实际路径)
379 var allMappings = new HashSet<string>();
380 foreach (var method in methodInfos)
381 {
382 var pathKey = method.Path;
383 if (allMappings.Add(pathKey))
384 {
385 sourceBuilder.AppendLine($" {{ \"{EscapeStringLiteral(pathKey)}\", \"{EscapeStringLiteral(pathKey)}\" }},");
386 }
387 if (!string.IsNullOrEmpty(method.Name) && allMappings.Add(method.Name!))
388 {
389 sourceBuilder.AppendLine($" {{ \"{EscapeStringLiteral(method.Name!)}\", \"{EscapeStringLiteral(pathKey)}\" }},");
390 }
298 391 }
299 392
300 393 sourceBuilder.AppendLine(@" };
@@ -306,6 +399,42 @@ namespace {namespaceName}
306 399 }
307 400 }
308 401
402 /// <summary>
403 /// 检查同类型(Request或Response)候选中是否存在重复的路径或名称键
404 /// </summary>
405 private static bool CheckDuplicateKeys(SourceProductionContext context, List<ClientRequestMethodCandidate> candidates, string className, string attributeName)
406 {
407 var seenKeys = new HashSet<string>();
408 var hasDuplicate = false;
409
410 foreach (var candidate in candidates)
411 {
412 if (!seenKeys.Add(candidate.Path))
413 {
414 context.ReportDiagnostic(Diagnostic.Create(
415 DuplicatePathRule,
416 candidate.MethodLocation.ToLocation(),
417 candidate.Path,
418 className,
419 attributeName));
420 hasDuplicate = true;
421 }
422
423 if (!string.IsNullOrEmpty(candidate.Name) && !seenKeys.Add(candidate.Name!))
424 {
425 context.ReportDiagnostic(Diagnostic.Create(
426 DuplicatePathRule,
427 candidate.MethodLocation.ToLocation(),
428 candidate.Name!,
429 className,
430 attributeName));
431 hasDuplicate = true;
432 }
433 }
434
435 return hasDuplicate;
436 }
437
309 438 /// <summary>
310 439 /// 转义字符串字面量中的特殊字符
311 440 /// </summary>
Modified XFEExtension.NetCore.ServerInteractive.SourceGenerator/Models/ClientRequestMethodCandidate.cs +2 -1
@@ -7,12 +7,13 @@ namespace XFEExtension.NetCore.ServerInteractive.SourceGenerator.Models;
7 7 /// <summary>
8 8 /// 客户端请求方法候选信息,包含验证所需的所有数据
9 9 /// </summary>
10 public class ClientRequestMethodCandidate(string namespaceName, string className, string methodName, string path, bool isRequest, bool isContainingTypePartial, int parameterCount, bool hasValidReturnType, string returnTypeName, LocationInfo methodLocation, LocationInfo classLocation, string typeParameters, string typeConstraints, string attributeName, string[] usingDirectives)
10 public class ClientRequestMethodCandidate(string namespaceName, string className, string methodName, string path, string? name, bool isRequest, bool isContainingTypePartial, int parameterCount, bool hasValidReturnType, string returnTypeName, LocationInfo methodLocation, LocationInfo classLocation, string typeParameters, string typeConstraints, string attributeName, string[] usingDirectives)
11 11 {
12 12 public string Namespace { get; } = namespaceName;
13 13 public string ClassName { get; } = className;
14 14 public string MethodName { get; } = methodName;
15 15 public string Path { get; } = path;
16 public string? Name { get; } = name;
16 17 public bool IsRequest { get; } = isRequest;
17 18 public bool IsContainingTypePartial { get; } = isContainingTypePartial;
18 19 public int ParameterCount { get; } = parameterCount;
Modified XFEExtension.NetCore.ServerInteractive/Attributes/RequestAttribute.cs +6 -1
@@ -3,7 +3,7 @@ namespace XFEExtension.NetCore.ServerInteractive.Attributes;
3 3 /// <summary>
4 4 /// 请求特性,用于标记IStandardRequestService中构造请求体的方法
5 5 /// </summary>
6 [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
6 [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
7 7 public class RequestAttribute : Attribute
8 8 {
9 9 /// <summary>
@@ -11,6 +11,11 @@ public class RequestAttribute : Attribute
11 11 /// </summary>
12 12 public string Path { get; }
13 13
14 /// <summary>
15 /// 请求名称(可选),使用请求器时可通过名称代替路径进行请求
16 /// </summary>
17 public string? Name { get; set; }
18
14 19 /// <summary>
15 20 /// 创建请求特性
16 21 /// </summary>
Modified XFEExtension.NetCore.ServerInteractive/Attributes/ResponseAttribute.cs +6 -1
@@ -3,7 +3,7 @@ namespace XFEExtension.NetCore.ServerInteractive.Attributes;
3 3 /// <summary>
4 4 /// 响应特性,用于标记IStandardRequestService中解析响应的方法
5 5 /// </summary>
6 [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
6 [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
7 7 public class ResponseAttribute : Attribute
8 8 {
9 9 /// <summary>
@@ -11,6 +11,11 @@ public class ResponseAttribute : Attribute
11 11 /// </summary>
12 12 public string Path { get; }
13 13
14 /// <summary>
15 /// 响应名称(可选),使用请求器时可通过名称代替路径进行请求
16 /// </summary>
17 public string? Name { get; set; }
18
14 19 /// <summary>
15 20 /// 创建响应特性
16 21 /// </summary>
Modified XFEExtension.NetCore.ServerInteractive/Implements/Requester/StandardRequestServiceBase.cs +3 -0
@@ -33,4 +33,7 @@ public abstract partial class StandardRequestServiceBase : IStandardRequestServi
33 33
34 34 /// <inheritdoc/>
35 35 public virtual Dictionary<string, Func<object>> ResponsePoints { get; } = new();
36
37 /// <inheritdoc/>
38 public virtual Dictionary<string, string> RequestRouteMap { get; } = new();
36 39 }
Modified XFEExtension.NetCore.ServerInteractive/Interfaces/Requester/IStandardRequestService.cs +4 -0
@@ -37,4 +37,8 @@ public interface IStandardRequestService : IRequestServiceBase
37 37 /// 响应方法字典,Key为请求路径,Value为对应的解析响应方法
38 38 /// </summary>
39 39 Dictionary<string, Func<object>> ResponsePoints { get; }
40 /// <summary>
41 /// 请求路由映射,Key为请求路径或名称,Value为实际路由路径(用于URL构建)
42 /// </summary>
43 Dictionary<string, string> RequestRouteMap { get; }
40 44 }
Modified XFEExtension.NetCore.ServerInteractive/Utilities/Extensions/XFEClientRequesterBuilderExtensions.cs +1 -1
@@ -75,7 +75,7 @@ public static class XFEClientRequesterBuilderExtensions
75 75 /// </summary>
76 76 /// <typeparam name="T">登录返回用户接口类型</typeparam>
77 77 /// <returns></returns>
78 public XFEClientRequesterBuilder AddLoginRequest<T>() where T : IUserFaceInfo => xFEClientRequesterBuilder.AddRequest<LoginRequestService<T>>("user/login").AddRequest<ReloginRequestService<T>>("user/relogin");
78 public XFEClientRequesterBuilder AddLoginRequest<T>() where T : IUserFaceInfo => xFEClientRequesterBuilder.AddRequest<LoginRequestService<T>>().AddRequest<ReloginRequestService<T>>();
79 79
80 80 /// <summary>
81 81 /// 使用XFE标准服务器服务请求
Modified XFEExtension.NetCore.ServerInteractive/Utilities/Requester/XFEClientRequester.cs +4 -31
@@ -20,7 +20,6 @@ public abstract class XFEClientRequester : IRequesterBase
20 20 private readonly JsonSerializerOptions _jsonSerializerOptions = new();
21 21 internal Dictionary<string, Func<IRequestService>> RequestServiceDictionary = [];
22 22 internal Dictionary<string, Func<IStandardRequestService>> StandardRequestServiceDictionary = [];
23 internal Dictionary<List<string>, Func<IStandardRequestService>> StandardMultiRequestServiceListDictionary = [];
24 23 internal Dictionary<string, StandardClientInstanceRequest> StandardClientInstanceRequestDictionary = [];
25 24 /// <inheritdoc/>
26 25 public string RequestAddress { get; set; } = string.Empty;
@@ -71,12 +70,14 @@ public abstract class XFEClientRequester : IRequesterBase
71 70 {
72 71 var xFEService = xFEServiceFactory();
73 72 xFEService.XFEClientRequester = this;
74 xFEService.Route = serviceName;
75 73 xFEService.DeviceInfo = DeviceInfo;
76 74 xFEService.Parameters = parameters;
75 // 通过RequestRouteMap解析实际路由路径
76 var actualRoute = xFEService.RequestRouteMap.TryGetValue(serviceName, out var route) ? route : serviceName;
77 xFEService.Route = actualRoute;
77 78 if (!xFEService.RequestPoints.TryGetValue(serviceName, out var requestHandler))
78 79 throw new XFERequesterException($"未找到路由'{serviceName}'对应的[Request]方法");
79 var (response, code) = await InteractiveHelper.GetServerResponse(RequestAddress + $"/{serviceName}", requestHandler(), _jsonSerializerOptions);
80 var (response, code) = await InteractiveHelper.GetServerResponse(RequestAddress + $"/{actualRoute}", requestHandler(), _jsonSerializerOptions);
80 81 result.StatusCode = code;
81 82 if (code == HttpStatusCode.OK)
82 83 {
@@ -113,34 +114,6 @@ public abstract class XFEClientRequester : IRequesterBase
113 114 result.Message = response;
114 115 }
115 116 }
116 foreach (var instance in from key in StandardMultiRequestServiceListDictionary.Keys where key.Contains(serviceName) select StandardMultiRequestServiceListDictionary[key] into factory select factory())
117 {
118 instance.XFEClientRequester = this;
119 instance.Route = serviceName;
120 instance.DeviceInfo = DeviceInfo;
121 instance.Parameters = parameters;
122 if (!instance.RequestPoints.TryGetValue(serviceName, out var requestHandler))
123 throw new XFERequesterException($"未找到路由'{serviceName}'对应的[Request]方法");
124 var (response, code) = await InteractiveHelper.GetServerResponse(RequestAddress + $"/{serviceName}", requestHandler(), _jsonSerializerOptions);
125 result.StatusCode = code;
126 if (code == HttpStatusCode.OK)
127 {
128 instance.Response = response;
129 instance.UnescapedResponse = Regex.Unescape(response);
130 if (instance.ResponsePoints.TryGetValue(serviceName, out var responseHandler))
131 {
132 var requestResult = responseHandler();
133 result.Result = requestResult;
134 }
135 MessageReceived?.Invoke(this, new ServerInteractiveEventArgsImpl("Success", code));
136 result.Message = "Success";
137 }
138 else
139 {
140 MessageReceived?.Invoke(this, new ServerInteractiveEventArgsImpl(response, code));
141 result.Message = response;
142 }
143 }
144 117 return result;
145 118 }
146 119 catch (Exception ex)
Modified XFEExtension.NetCore.ServerInteractive/Utilities/Requester/XFEClientRequesterBuilder.cs +22 -26
@@ -15,7 +15,6 @@ public abstract class XFEClientRequesterBuilder : XFEBuilderBase<XFEClientReques
15 15 private readonly XFEClientRequester _xFEClientRequester = new XFEClientRequesterImpl();
16 16 private readonly Dictionary<string, Func<IRequestService>> _requestServiceDictionary = [];
17 17 private readonly Dictionary<string, Func<IStandardRequestService>> _standardRequestServiceDictionary = [];
18 private readonly Dictionary<List<string>, Func<IStandardRequestService>> _standardMultiRequestServiceListDictionary = [];
19 18 private readonly Dictionary<string, StandardClientInstanceRequest> _standardClientInstanceRequestDictionary = [];
20 19 /// <summary>
21 20 /// 创建构建器
@@ -46,36 +45,34 @@ public abstract class XFEClientRequesterBuilder : XFEBuilderBase<XFEClientReques
46 45 }
47 46
48 47 /// <summary>
49 /// 添加标准请求器
48 /// 注册标准请求服务(从RequestPoints/ResponsePoints/RequestRouteMap自动获取路由路径和名称)
50 49 /// </summary>
51 50 /// <typeparam name="T">请求服务泛型</typeparam>
52 /// <param name="serviceName">请求服务名称</param>
53 51 /// <returns></returns>
54 public XFEClientRequesterBuilder AddRequest<T>(string serviceName) where T : IStandardRequestService, new()
52 public XFEClientRequesterBuilder AddRequest<T>() where T : IStandardRequestService, new()
55 53 {
56 _standardRequestServiceDictionary.Add(serviceName, () =>
57 {
58 var inst = new T();
59 ApplyParameter(inst);
60 return inst;
61 });
62 return this;
63 }
54 var probeService = new T();
55 ApplyParameter(probeService);
64 56
65 /// <summary>
66 /// 添加标准请求器
67 /// </summary>
68 /// <typeparam name="T">请求服务泛型</typeparam>
69 /// <param name="serviceName">请求服务名称</param>
70 /// <returns></returns>
71 public XFEClientRequesterBuilder AddRequest<T>(List<string> serviceName) where T : IStandardRequestService, new()
72 {
73 _standardMultiRequestServiceListDictionary.Add(serviceName, () =>
57 var routeKeys = probeService.RequestPoints.Keys
58 .Concat(probeService.ResponsePoints.Keys)
59 .Concat(probeService.RequestRouteMap.Keys)
60 .Distinct()
61 .ToList();
62
63 if (routeKeys.Count == 0)
64 throw new InvalidOperationException($"类型 {typeof(T).Name} 的 RequestPoints/ResponsePoints 为空");
65
66 // 为每个路径/名称注册服务工厂
67 foreach (var key in routeKeys)
74 68 {
75 var inst = new T();
76 ApplyParameter(inst);
77 return inst;
78 });
69 _standardRequestServiceDictionary.Add(key, () =>
70 {
71 var inst = new T();
72 ApplyParameter(inst);
73 return inst;
74 });
75 }
79 76 return this;
80 77 }
81 78
@@ -115,7 +112,6 @@ public abstract class XFEClientRequesterBuilder : XFEBuilderBase<XFEClientReques
115 112 _xFEClientRequester.DeviceInfo = options.DeviceInfo;
116 113 _xFEClientRequester.RequestServiceDictionary = _requestServiceDictionary;
117 114 _xFEClientRequester.StandardRequestServiceDictionary = _standardRequestServiceDictionary;
118 _xFEClientRequester.StandardMultiRequestServiceListDictionary = _standardMultiRequestServiceListDictionary;
119 115 _xFEClientRequester.StandardClientInstanceRequestDictionary = _standardClientInstanceRequestDictionary;
120 116 return _xFEClientRequester;
121 117 }