【问题标题】:How to inject dependencies into a MassTransitStateMachine activity?如何将依赖项注入 MassTransitStateMachine 活动?
【发布时间】:2021-02-24 11:40:30
【问题描述】:

我被卡住了,lib 的码头没有帮助。鉴于以下传奇定义:

public class GetOrdersStateMachine : MassTransitStateMachine<GetOrdersState>
{
    public State? FetchingOrdersAndItems { get; private set; }

    public Event<GetOrders>? GetOrdersIntegrationEventReceived { get; private set; }

    public GetOrdersStateMachine()
    {
        Initially(
            When(GetOrdersIntegrationEventReceived)
                .Activity(AddAccountIdToState)
                .TransitionTo(FetchingOrdersAndItems));
    }

    private EventActivityBinder<GetOrdersState, GetOrders> AddAccountIdToState(
        IStateMachineActivitySelector<GetOrdersState, GetOrders> sel) =>
        sel.OfType<AddAccountIdToStateActivity>();
}

以及下面的活动定义:

public class AddAccountIdToStateActivity : Activity<GetOrdersState, GetOrders>
{
    private readonly IPartnerService _partnerService;

    public AddAccountIdToStateActivity(IPartnerService partnerService) => _partnerService = partnerService;

    public void Probe(ProbeContext context) => 
        context.CreateScope($"GetOrders{nameof(AddAccountIdToStateActivity)}");

    public void Accept(StateMachineVisitor visitor) => visitor.Visit(this);

    public async Task Execute(
        BehaviorContext<GetOrdersState, GetOrders> context,
        Behavior<GetOrdersState, GetOrders> next)
    {
        context.Instance.AccountId = await _partnerService.GetAccountId(context.Data.PartnerId);

        await next.Execute(context);
    }

    public Task Faulted<TException>(
        BehaviorExceptionContext<GetOrdersState, GetOrders, TException> context,
        Behavior<GetOrdersState, GetOrders> next) where TException : Exception => 
        next.Faulted(context);
}

以及下面的测试定义:

var machine = new GetOrdersStateMachine();
var harness = new InMemoryTestHarness();
var sagaHarness = harness.StateMachineSaga<GetOrdersState, GetOrdersStateMachine>(machine);
var @event = new GetOrders("1", new[] {MarketplaceCode.De}, DateTime.UtcNow);

await harness.Start();

try
{
    await harness.Bus.Publish(@event);
    await harness.Bus.Publish<ListOrdersErrorResponseReceived>(new
    {
        @event.CorrelationId,
        AmazonError = "test"
    });

    var errorMessages = sagaHarness.Consumed.Select<ListOrdersErrorResponseReceived>().ToList();
    var sagaResult = harness.Published.Select<AmazonOrdersReceived>().ToList();
    var state = sagaHarness.Sagas.Contains(@event.CorrelationId);

    harness.Consumed.Select<GetOrders>().Any().Should().BeTrue();
    sagaHarness.Consumed.Select<GetOrders>().Any().Should().BeTrue();
    harness.Consumed.Select<ListOrdersErrorResponseReceived>().Any().Should().BeTrue();
    errorMessages.Any().Should().BeTrue();
    sagaResult.First().Context.Message.IsFaulted.Should().BeTrue();
    errorMessages.First().Context.Message.CorrelationId.Should().Be(@event.CorrelationId);
    errorMessages.First().Context.Message.AmazonError.Should().Be("test");
    state.IsFaulted.Should().BeTrue();
}
finally
{
    await harness.Stop();
}

如您所见,AddAccountToStateActivity 依赖于IPartnerService。我想不出一种方法来配置该依赖项。文档中没有任何内容,我也无法在 github 上找到任何内容。我该怎么做?

【问题讨论】:

    标签: c# unit-testing masstransit


    【解决方案1】:

    感谢图书馆的一位作者的帮助,我最终编写了这段代码:

    private static (InMemoryTestHarness harness, IStateMachineSagaTestHarness<GetOrdersState, GetOrdersStateMachine> sagaHarness) ConfigureAndGetHarnesses()
    {
        var provider = new ServiceCollection()
            .AddMassTransitInMemoryTestHarness(cfg =>
            {
                cfg.AddSagaStateMachine<GetOrdersStateMachine, GetOrdersState>().InMemoryRepository();
                cfg.AddSagaStateMachineTestHarness<GetOrdersStateMachine, GetOrdersState>();
            })
            .AddLogging()
            .AddSingleton(Mock.Of<IPartnerService>())
            .AddSingleton(Mock.Of<IStorage>())
            .BuildServiceProvider(true);
        var harness = provider.GetRequiredService<InMemoryTestHarness>();
        var sagaHarness = provider
            .GetRequiredService<IStateMachineSagaTestHarness<GetOrdersState, GetOrdersStateMachine>>();
        
        return (harness, sagaHarness);
    }
    

    如您所见,我正在使用 ServiceProvider 注册我的模拟。

    【讨论】:

    • 很高兴你能成功。还被问到here,它链接了你找到的文档。
    猜你喜欢
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    相关资源
    最近更新 更多