EntityFrameworkSagaRepository with Scoped Context throws ObjectDisposedException

241 views
Skip to first unread message

Алексей Токарев

unread,
Oct 15, 2018, 2:05:44 AM10/15/18
to masstransit-discuss
If I register Entity Framework Context in IOC (from Microsoft.Extensions) as Scoped, EntityFrameworkSagaRepository.Send
 works successfuly only once (saving some saga's state). The second attempt to call the method is 
followed by System.ObjectDisposedException

System.ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur
 if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'TradingContext'.
   at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
   at Microsoft.EntityFrameworkCore.DbContext.get_Database()
   at MassTransit.EntityFrameworkCoreIntegration.Saga.EntityFrameworkSagaRepository`1.MassTransit.Saga.ISagaRepository<TSaga>.Send[T](ConsumeContext`1 context, ISagaPolicy`2 policy, IPipe`1 next)
   at MassTransit.Saga.Pipeline.Filters.CorrelatedSagaFilter`2.GreenPipes.IFilter<MassTransit.ConsumeContext<TMessage>>.Send(ConsumeContext`1 context, IPipe`1 next)
   at MassTransit.Saga.Pipeline.Filters.CorrelatedSagaFilter`2.GreenPipes.IFilter<MassTransit.ConsumeContext<TMessage>>.Send(ConsumeContext`1 context, IPipe`1 next)
   at GreenPipes.Filters.RetryFilter`1.GreenPipes.IFilter<TContext>.Send(TContext context, IPipe`1 next)


Registering Context as Transient helps, but I need Scoped to work with generic Unit Of Work pattern im my business logic.


Here is the declaration of my statemachine:

           busConfig.Add(
                StateMachineQueuePrefixes.TradingLotStateMachineQueuePrefix + "." + AuctionTypeConstants.Template1, 
                e => 
                { 
                    Func<DbContext> ContextFactory = serviceProvider.GetRequiredService<DbContext>;                           
                    var tradeLotSagaRepository =
                        new EntityFrameworkSagaRepository<LotSaga>(ContextFactory,
                            IsolationLevel.Serializable,
                            true,
                            null,
                            postgresRelationalMetadataHelper);
                    {
                        e.StateMachineSaga(serviceProvider.GetRequiredService<LotStateMachine>(), tradeLotSagaRepository);
                    }                    
                });


Here is registration in IOC:

     .AddScoped<DbContext, TradingContext>()           
     .AddDbContext<TradingContext>(opt => opt.UseNpgsql(connectionString), ServiceLifetime.Scoped);
Reply all
Reply to author
Forward
0 new messages