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

В 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 и пользовательские атрибуты 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

Мой 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 # успешно;Я просто борюсь с этим шаблоном ручного вызова.

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

1 Ответ

0 голосов
/ 07 июня 2018

Отладка через источник WebJobs, я в итоге оказался в DefaultTypeLocator , который выбирает классы, помеченные 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 их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...