/
Component Extensions.vb
55 lines (51 loc) · 2.78 KB
/
Component Extensions.vb
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
Namespace Components
Public Module IBotComponentExtensions
<Extension()>
<CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
Public Sub UIInvokeCommand(component As IBotComponent, argument As String)
Contract.Requires(component IsNot Nothing)
Contract.Requires(argument IsNot Nothing)
Try
Dim i = argument.IndexOf(" "c)
If i = -1 Then i = argument.Length
Dim subcommand = argument.Substring(0, i).ToInvariant
Dim argDesc = If(component.IsArgumentPrivate(subcommand), "{0} [arguments hidden]".Frmt(subcommand), argument)
component.Logger.Log("Command: {0}".Frmt(argDesc), LogMessageType.Typical)
component.Logger.FutureLog(placeholder:="[running command {0}...]".Frmt(argDesc),
message:=SafeInvokeCommand(component, argument).AssumeNotNull(),
messageType:=LogMessageType.Typical)
Catch e As Exception
e.RaiseAsUnexpected("UIInvokeCommand for {0}:{1}".Frmt(component.Type, component.Name))
End Try
End Sub
Private Async Function SafeInvokeCommand(component As IBotComponent, argument As String) As Task(Of String)
Contract.Assume(component IsNot Nothing)
Contract.Assume(argument IsNot Nothing)
'Contract.Ensures(Contract.Result(Of Task(Of String))() IsNot Nothing)
Try
Dim result = Await Await Task.Factory.StartNew(Function() component.InvokeCommand(Nothing, argument))
If String.IsNullOrEmpty(result) Then Return "Succeeded with no message"
Return result
Catch ex As Exception
Return "Failed: {0}".Frmt(ex.Summarize)
End Try
End Function
<Extension()>
Public Async Function IncludeAllCommands(component As IBotComponent, commands As IEnumerable(Of Commands.ICommand(Of IBotComponent))) As Task(Of IDisposable)
Contract.Assume(component IsNot Nothing)
Contract.Assume(commands IsNot Nothing)
'Contract.Ensures(Contract.Result(Of Task(Of IDisposable))() IsNot Nothing)
Dim disposables = New List(Of Task(Of IDisposable))
Try
For Each command In commands
disposables.Add(component.IncludeCommand(command))
Next command
Await Task.WhenAll(disposables)
Return New DelegatedDisposable(Sub() disposables.DisposeAllAsync())
Catch ex As Exception
disposables.DisposeAllAsync()
Throw
End Try
End Function
End Module
End Namespace