Используя Durable Functions, как вернуть несколько значений из Activity Activity - PullRequest
1 голос
/ 14 февраля 2020

Я большой фанат и разработчик доменного дизайна и всегда пытаюсь отобразить технологию / архитектуру в мире DDD. Отображение микросервисов в ограниченном контексте обеспечивает естественный брак. В конце концов, я просто хочу сосредоточиться на своей бизнес логике c и разместить ее в правильной среде. Durable Functions выглядело многообещающе для меня, когда мне нужно было решить проблему распределенных транзакций между микросервисами, Sagas или Process Manager. Я использую NServicebus в течение многих лет и люблю их технологию Saga, но хотел бы использовать оркестровки Durable Function для обработки saga logi c. Проблема архитектуры, с которой я сейчас сталкиваюсь, заключается в следующем. Я сопоставил службу приложений DDD с функцией деятельности. Saga, следовательно, будет создан просто с Orchestrator, нажав правильный набор функций деятельности для выполнения своих транзакций. Концептуально сделать откат довольно просто, но у меня возникла проблема с реализацией. Кроме того, каждая функция Activity делегирует библиотеке, которая обрабатывает все детали бизнес-логики c, а затем берет список событий, возвращаемых бизнес-логиками c, и возвращает их обратно в Orchestrator. Насколько я исследовал, нет способа вернуть полиморфное c возвращаемое значение из Activity Activity. Так что, если моя бизнес-логика c генерирует событие UpdateSucceeded или UpdateFailed, как бы мне просто вернуть это из моей функции Activity обратно в Orchestrator, чтобы Orchestrator мог предпринять корректирующие действия, вызвав отдельные функции Activity отката отката?

Ответы [ 3 ]

2 голосов
/ 27 февраля 2020

Для этого можно использовать новую пользовательскую поддержку сериализатора в Durable Functions 2.1.0 . Это все еще нужно документировать, но в основном это работает следующим образом: Azure Функции Внедрение зависимостей :

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.Services.AddSingleton<IMessageSerializerSettingsFactory, CustomMessageSerializer>();
    }
}

public class CustomMessageSerializer : IMessageSerializerSettingsFactory
{
    public JsonSerializerSettings CreateJsonSerializerSettings()
    {
        return new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
    }
}

Теперь, если у вас есть такие классы:

public abstract class Thing
{
    public abstract string GetMessage();
}

public class Foo : Thing
{
    public override string GetMessage()
    {
        return "I'm a Foo";
    }
}

public class Bar : Thing
{
    public override string GetMessage()
    {
        return "I'm a Bar";
    }
}

И у вас есть такие функции оркестровки и активности:

[FunctionName(nameof(Orchestrator))]
public static async Task<List<string>> Orchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add((await context.CallActivityAsync<Thing>(nameof(GetThing), true)).GetMessage());
    outputs.Add((await context.CallActivityAsync<Thing>(nameof(GetThing), false)).GetMessage());

    // [ "I'm a Foo", "I'm a Bar" ]
    return outputs;
}

[FunctionName(nameof(GetThing))]
public static Thing GetThing([ActivityTrigger] bool isFoo, ILogger log)
    => isFoo ? (Thing)new Foo() : (Thing)new Bar();

Приведенный выше пользовательский сериализатор применяется ко всему, сериализованному расширением Durable Functions. Вы можете создать более сложный сериализатор, если хотите больше контроля.

0 голосов
/ 16 февраля 2020

Конечно, добавление кода сериализации до и после вызова будет работать, но ниже оптимального. Сигнатура функции деятельности потеряет свою специфику типа. Работоспособный, но не очень элегантный.

0 голосов
/ 14 февраля 2020

Несмотря на то, что вы, возможно, не сможете вернуть полиморф c, полученный в результате действия, вы рассматривали вопрос о возвращении сериализованного значения, которое может быть десериализовано Orchestrator и обработано соответствующим образом. Это не идеально, но даст вам возможность выполнить ту же задачу.

...