microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v2.0.0-preview.5

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

Libraries/Microsoft.Teams.Apps/Routing/Route.cs

91lines · modecode

1using System.Reflection;
2
3using Microsoft.Teams.Api.Activities;
4using Microsoft.Teams.Apps.Activities;
5using Microsoft.Teams.Apps.Annotations;
6using Microsoft.Teams.Common.Extensions;
7
8namespace Microsoft.Teams.Apps.Routing;
9
10public interface IRoute
11{
12 public bool Select(IActivity activity);
13 public Task<object?> Invoke(IContext<IActivity> context);
14}
15
16public class Route : IRoute
17{
18 public string? Name { get; set; }
19 public required Func<IActivity, bool> Selector { get; set; }
20 public required Func<IContext<IActivity>, Task<object?>> Handler { get; set; }
21
22 public bool Select(IActivity activity) => Selector(activity);
23 public async Task<object?> Invoke(IContext<IActivity> context) => await Handler(context);
24}
25
26public class AttributeRoute : IRoute
27{
28 public required ActivityAttribute Attr { get; set; }
29 public required MethodInfo Method { get; set; }
30 public object? Object { get; set; }
31
32 public bool Select(IActivity activity) => Attr.Select(activity);
33 public ValidationResult Validate()
34 {
35 var result = new ValidationResult();
36
37 foreach (var param in Method.GetParameters())
38 {
39 var attribute = param.GetCustomAttribute<ContextAccessorAttribute>(true);
40 var generic = param.ParameterType.GenericTypeArguments.FirstOrDefault();
41 var isContext = generic?.IsAssignableTo(Attr.Type) ?? false;
42
43 if (attribute is null && !isContext)
44 {
45 result.AddError(param.Name ?? "??", "type must be `IContext<TActivity>` or an `IContext` accessor attribute");
46 }
47 }
48
49 return result;
50 }
51
52 public Task<object?> Invoke(IContext<IActivity> context)
53 {
54 var args = Method.GetParameters().Select(param =>
55 {
56 var attribute = param.GetCustomAttribute<ContextAccessorAttribute>(true);
57 return attribute is null ? Attr.Coerce(context) : attribute.GetValue(context, param);
58 });
59
60 return Method.InvokeAsync(Object, args?.ToArray());
61 }
62
63 public class ValidationResult
64 {
65 /// <summary>
66 /// the errors that were found
67 /// </summary>
68 public IList<ParameterError> Errors { get; set; } = [];
69
70 /// <summary>
71 /// is the result valid
72 /// </summary>
73 public bool Valid => Errors.Count == 0;
74
75 /// <summary>
76 /// combine all the errors into
77 /// one message string
78 /// </summary>
79 public override string ToString() => string.Join(Environment.NewLine, Errors.Select(err => $"{err.Name} => {err.Message}"));
80
81 /// <summary>
82 /// add a parameter error to the result
83 /// </summary>
84 public void AddError(string name, string message)
85 {
86 Errors.Add(new(name, message));
87 }
88
89 public record ParameterError(string Name, string Message);
90 }
91}