When using IScriptHost.RunMethod() or IScriptRun.RunMethod() there is no guarantee that the class or method does exists in the script.
If a class or method does not exists, there will is no exception thrown or indicator that the method was not run at all. Just no code is executed.
Is there a way to lookup a method / class beforehand, so that i can check if those exists? Like IScriptHost.HasMethod(string methodName) and IScriptRun.HasMethod(string methodName)?
In addition having a IScriptRun.HasType(Type type) / IScriptRun.HasType(string typeName) would be useful too.
Of course the best way in my oppinion would be that the RunMethod() throws an Exception or returns either a Error State or the resulting type. For that something like OneOf<> would be perfect. In addition you could add another signature for RunMethod() and RunMethodAsync() that allows to set a generic for the resulting type.
For the moment, is there a workaround for looking up the method in the AST?
We have already implemented HasMethod and FindMethod in the master branch and will include this feature in the next build. As for HasType and the generic version of RunMethod, I will study them and respond to you shortly. In the meantime, you can use the ScriptAssembly property after you compile the script. This property allows you to access any script method or property via reflection.
Here is an example for VB:
Dim assembly = ScriptRun1.ScriptHost.ScriptAssembly
Dim inst = assembly.CreateInstance("ScriptSpace.ScriptClass")
Dim propInfoShared = inst.GetType().GetProperty("GlobalProp")
propInfoShared.SetValue(Nothing, "new shared value from main app")
Dim valShared = propInfoShared.GetValue(Nothing)
Dim propInfoInstance = inst.GetType().GetProperty("InstanceProp")
propInfoInstance.SetValue(inst, "new instance value from main app")
Dim valInstance = propInfoInstance.GetValue(inst)
In script:
Imports System
Imports System.Drawing
Imports System.Diagnostics
Imports System.Windows.Forms
Imports Microsoft.VisualBasic
Namespace ScriptSpace
Partial Public Class ScriptClass
Public Shared ReadOnly Property SharedDefault As ScriptClass = New ScriptClass()
' Instance field initialized inline
Private count As Integer = 5
' Shared (static) field initialized inline
Public Shared globalVar As String = "olala"
' Compile-time constant
Public Const Pi As Double = 3.14159265358979
Public Shared Property GlobalProp As String
Get
Return globalVar
End Get
Set(value As String)
globalVar = value
End Set
End Property
Public Property InstanceProp As String
Get
Return globalVar
End Get
Set(value As String)
globalVar = value
End Set
End Property
' Read-only field - can be initialized inline or in the constructor
Private ReadOnly createdAt As Date = Date.UtcNow
Public Shared Sub Main(text As String)
MsgBox("Main app says: " & text & " and " & globalVar)
External.X = 10
External.MainWindowText = "Text set from ScriptClass"
End Sub
Public Shared Function GetData() As Integer
Return External.X
End Function
End Class
End Namespace
We have also added an additional parameter to RunMethod that specifies whether to throw an exception when the method is not found. This feature will also be available in the next build. I will post an update here when the new build is available and on how we will proceed with the other features you requested.