Как я могу объявить функцию в F #, которую можно вызвать через JobHost.CallAsync WebJob?

jrr спросил: 12 мая 2018 в 04:49 в: .net

В C # WebJob я могу вручную вызвать общедоступный метод статического класса следующим образом:

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;namespace foo
{
    public class Program
    {        [NoAutomaticTrigger]
        public static void Go(TraceWriter log) { ... }        static void Main()
        {
           var host = new JobHost();
           var methodInfo = typeof(Program).GetMethod("Go");
           host.Call(methodInfo);
           host.RunAndBlock();
        }

methodInfo - это System.Reflection.MethodInfo , а в отладчике я вижу, что он имеет атрибуты Public | Static | HideBySig и CustomAttributes Microsoft.Azure.WebJobs.NoAutomaticTriggerAttribute.

Я пытаюсь сделайте это в F #. Вот что я до сих пор:

type Foo() =    [<NoAutomaticTrigger>]
    static member Go (log:TraceWriter) =
        log.Info "hello!"[<EntryPoint>]
let main argv =
        let theType = typedefof<Foo>
        let methodInfo = theType.GetMethods() |> Seq.find(fun t -> t.Name = "Go")
        host.Call(methodInfo)
        host.RunAndBlock()

Время выполнения WebJobs не нравится:

System.InvalidOperationException
  HResult=0x80131509
  Message='Void Go(Microsoft.Azure.WebJobs.Host.TraceWriter)' can't be invoked from Azure WebJobs SDK. Is it missing Azure WebJobs SDK attributes?
  Source=Microsoft.Azure.WebJobs.Host
  StackTrace:
   at Microsoft.Azure.WebJobs.JobHost.Validate(IFunctionDefinition function, Object key)
   at Microsoft.Azure.WebJobs.JobHost.<CallAsyncCore>d__37.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.JobHost.Call(MethodInfo method)
   at Program.main(String[] argv) in C:\path\to\project\Program.fs:line 110

My F # methodInfo имеет атрибут NoAutomaticTrigger. Он также имеет Public и Static, но отсутствует HideBySig . Это может иметь значение? Существуют ли другие части MethodInfos, которые я должен сравнивать?

Вот соответствующий источник из webjobs sdk: https://github.com/Azure/azure-webjobs-sdk/blob/v2.2.0 /src/Microsoft.Azure.WebJobs.Host/JobHost.cs#L306

Для чего это стоит, я смог успешно использовать TimerTrigger и ServiceBusTrigger из F #; это всего лишь шаблон ручного вызова, с которым я борюсь.

Затем я планирую просеять через источник webjobs и попытаться выяснить, что именно он ищет, но я надеюсь, что есть что-то очевидное кто-то более опытный с F # и / или webjobs может сказать мне.

1 ответ

Есть решение
jrr ответил: 14 мая 2018 в 02:08

Отладка через источник WebJobs, я в конечном итоге попал в theDefaultTypeLocator, который собирает классы, отмеченные как IsPublic. Я экспериментировал с моими декларациями F #, но не мог этого добиться; Мне удалось создать IsNestedPublic.

Итак, я попробовал другой подход: вместо того, чтобы пытаться написать функцию F #, доступную для существующей среды выполнения WebJobs, я перепробовал логику обнаружения:

type myTypeLocator() =
    interface ITypeLocator with
        member this.GetTypes () =
            new System.Collections.Generic.List<Type>([ typedefof<Foo> ]) :> IReadOnlyList<Type>

...

let config = new JobHostConfiguration (
                    DashboardConnectionString = dashboardConnectionString,
                    StorageConnectionString = storageConnectionString,
                    TypeLocator = new myTypeLocator()
                )let host = new JobHost(config)

Это сработало: мои функции обнаружены, и я могу JobHost.Call их.