ConnectorEx/Resolver.cs
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license.
4 //
5 // Microsoft Bot Framework: http://botframework.com
6 //
7 // Bot Builder SDK GitHub:
8 // https://github.com/Microsoft/BotBuilder
9 //
10 // Copyright (c) Microsoft Corporation
11 // All rights reserved.
12 //
13 // MIT License:
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33 
34 using Microsoft.Bot.Connector;
35 using System;
36 using System.Collections.Generic;
37 using System.Linq;
38 using System.Text;
39 using System.Threading;
40 using System.Threading.Tasks;
41 
42 namespace Microsoft.Bot.Builder.Scorables.Internals
43 {
47  public sealed class ActivityResolver : DelegatingResolver
48  {
50  : base(inner)
51  {
52  }
53 
54  public static readonly IReadOnlyDictionary<string, Type> TypeByName = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase)
55  {
60  { ActivityTypes.Ping, typeof(IActivity) },
61  { ActivityTypes.Event, typeof(IEventActivity) },
64  };
65 
66  public override bool TryResolve(Type type, object tag, out object value)
67  {
68  if (tag == null)
69  {
70  // if type is Activity, we're not delegating to the inner IResolver.
71  if (typeof(IActivity).IsAssignableFrom(type))
72  {
73  // if we have a registered IActivity
74  IActivity activity;
75  if (this.inner.TryResolve<IActivity>(tag, out activity))
76  {
77  // then make sure the IActivity.Type allows the desired type
78  Type allowedType;
79  if (TypeByName.TryGetValue(activity.Type, out allowedType))
80  {
81  if (type.IsAssignableFrom(allowedType))
82  {
83  // and make sure the actual CLR type also allows the desired type
84  // (this is true most of the time since Activity implements all of the interfaces)
85  Type clrType = activity.GetType();
86  if (allowedType.IsAssignableFrom(clrType))
87  {
88  value = activity;
89  return true;
90  }
91  }
92  }
93  }
94 
95  // otherwise we were asking for IActivity and it wasn't assignable from the IActivity.Type
96  value = null;
97  return false;
98  }
99  }
100 
101  // delegate to the inner for all remaining type resolutions
102  return base.TryResolve(type, tag, out value);
103  }
104  }
105 
106  public abstract class PropertyResolver<T> : DelegatingResolver
107  {
109  : base(inner)
110  {
111  }
112 
113  protected abstract object PropertyFrom(T item);
114 
115  public override bool TryResolve(Type type, object tag, out object value)
116  {
117  T item;
118  if (this.inner.TryResolve(tag, out item))
119  {
120  var property = PropertyFrom(item);
121  if (property != null)
122  {
123  var propertyType = property.GetType();
124  if (type.IsAssignableFrom(propertyType))
125  {
126  value = property;
127  return true;
128  }
129  }
130  }
131 
132  return base.TryResolve(type, tag, out value);
133  }
134  }
135 
136  public sealed class EventActivityValueResolver : PropertyResolver<IEventActivity>
137  {
139  : base(inner)
140  {
141  }
142 
143  protected override object PropertyFrom(IEventActivity item)
144  {
145  return item.Value;
146  }
147  }
148 
149  public sealed class InvokeActivityValueResolver : PropertyResolver<IInvokeActivity>
150  {
152  : base(inner)
153  {
154  }
155 
156  protected override object PropertyFrom(IInvokeActivity item)
157  {
158  return item.Value;
159  }
160  }
161 }
const string Event
Asynchronous external event
const string Invoke
Synchronous request to invoke a command
override bool TryResolve(Type type, object tag, out object value)
Namespace for the Microsoft Bot Connector SDK.
Synchronous request to invoke an operation
const string ContactRelationUpdate
Bot added removed to contact list
A user has added a bot to their contact list, removed the bot from their contact list, or otherwise changed the relationship between user and bot
Allow the resolution of values based on type and optionally tag.
override bool TryResolve(Type type, object tag, out object value)
const string Message
Message from a user -> bot or bot -> User
const string Ping
Bounce a message off of the server without replying or changing it&#39;s state
The referenced conversation has been updated
const string DeleteUserData
Delete user data
Asynchronous external event
Shared properties for all activities
Definition: IActivity.cs:9
const string Typing
a user is typing
const string ConversationUpdate
This notification is sent when the conversation&#39;s properties change, for example the topic name...
A resolver to recover C# type information from Activity schema types.