Hi, I'm trying to create a State Machine Saga for integration purposes. In a State I need to check in the database if the current register already exists to purge it from the integration. And I thinked to put that in the saga's depency injection the DbContext, but I had a problem, the DbContext is scoped and I saw it in the source code the Masstransit saga implementation is a singleton. I tried to find some examples about a similar implementation, but I could'nt find any one. Have someone to help me and others about it? Need I put that dependency on the saga's instance?
You should put the dependency in an activity, that you call from the state machine. I'm not sure if I have documented that yet 鈥撀爄t's on the list. The unit test shows how to do it:
The dependency should be on the Activity, not the state machine or instance.
It's awesome @phatboyg thank you so much. I'm making the changes in my code and let me get it work. I want to post here my implementation for someone in future. I saw today in MassTransit to find about Activities, and discovered that the community improved the documentation, it's get it so better.
Dependency Injection Registrations
``` config.Collection.AddScoped
config.Collection.AddScoped
config.Collection.AddScoped
config.Collection.AddScoped
config.Collection.RegisterInMemorySagaRepository
config.AddSagaStateMachine
Receive endpoint configuration
cfg.ReceiveEndpoint(host, nespressoSulVerifyConfig.QueueName, e => {
e.BindMessageExchanges = false;
e.ConfigureSaga<VerificationLayoutSagaInstance>(provider);
});
And I put the DbContext in the VerificationLayoutActivity.
public class VerificationLayoutSaga : MassTransitStateMachine<VerificationLayoutSagaInstance>
{
#region States
public State Verificate { get; private set; }
public State Reject { get; private set; }
public State Integrate { get; private set; }
#endregion States
#region Events
public Event<IAquireFile> AcquireFile { get; private set; }
#endregion Events
#region Definition
public VerificationLayoutSaga()
{
InstanceState(instance => instance.CurrentState);
//Events
Event(() => AcquireFile, x => x.CorrelateBy<Guid>(instance => instance.Lot, context => context.Message.Lot));
SetCompletedWhenFinalized();
//Executions
Initially(
When(AcquireFile)
.Then(context => {
context.Instance.Customer = context.Data.Customer;
context.Instance.Name = context.Data.Name;
context.Instance.FullName = context.Data.FullName;
context.Instance.Date = context.Data.Date;
context.Instance.Lot = context.Data.Lot;
})
.Activity(acquire => acquire.OfInstanceType<AcquireFileActivity>())
.TransitionTo(Verificate));
WhenEnter(Verificate,
bind => bind
.Activity(verify => verify.OfType<VerificationLayoutActivity>())
.IfElse(
context => !context.Instance.Validated,
then => then.TransitionTo(Reject),
thenElse => thenElse.TransitionTo(Integrate)));
WhenEnter(Reject,
bind => bind
.Activity(reject => reject.OfType<RejectFileActivity>())
.Finalize());
WhenEnter(Integrate,
bind => bind
.Activity(integrate => integrate.OfType<IntegrateFileActivity>())
.Finalize());
}
#endregion Definition
}
```
Thanks for sharing your solution!
Most helpful comment
You should put the dependency in an activity, that you call from the state machine. I'm not sure if I have documented that yet 鈥撀爄t's on the list. The unit test shows how to do it:
Registration: https://github.com/MassTransit/MassTransit/blob/master/src/Containers/MassTransit.Containers.Tests/DependencyInjection_Tests/DependencyInjection_SagaStateMachine.cs#L36
State machine:
https://github.com/MassTransit/MassTransit/blob/master/src/Containers/MassTransit.Containers.Tests/Scenarios/StateMachines/TestStateMachineSaga.cs#L28
The dependency should be on the Activity, not the state machine or instance.