2

My application: .Net6 and used MediatR to handle domain events. when I try to get the data from database, i get the following error:

Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This m ay occur if you are calling 'Dispose' on the context instance, or wrapping it 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: 'ApplicationDbContext'.

I override savechanges as follow:

public class DomainEventPublishingInterceptor:SaveChangesInterceptor
{
    private readonly IMediator _mediator;

    public DomainEventPublishingInterceptor(IMediator mediator)
    {
        _mediator = mediator;
    }
     public override ValueTask<int> SavedChangesAsync(SaveChangesCompletedEventData eventData, int result, CancellationToken cancellationToken = new())
    { 
        foreach (var entityEntry in eventData.Context.ChangeTracker.Entries<IAggregateRoot>()) PublishEvents(entityEntry.Entity);
        return new ValueTask<int>(result);
    }

...
...

In program.cs I inject MediatR using AddMediator extension:

public static IServiceCollection AddMediator(this IServiceCollection services,
        params Assembly[] assemblies)
    {
        services.AddMediatR(assemblies);
        return services;
    }

DbContext register:

services.AddDbContext<ApplicationDbContext>((provider, options) =>
            {
                options.UseSqlServer(configuration["ConnectionStrings:Cnn"],
                        b =>
                        {
                            b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName);
                            b.MigrationsHistoryTable("__ApplicationDbContextMigrationHistory",
                                "dbo");
                        })
                    .EnableSensitiveDataLogging()
                    .EnableDetailedErrors();
                options.AddInterceptors(
                    new DomainEventPublishingInterceptor(provider.GetRequiredService<IMediator>())
                );
            });

and finally after rasing any event I have a Notification handler:

public class PushRequestEventHandler:INotificationHandler<ProductApproved>
{
    private readonly ApplicationDbContext _db;
    public PushRequestEventHandler(ApplicationDbContext db)
    {
        _db = db;
    }
public async Task Handle(ProductApproved notification, CancellationToken cancellationToken)
    {
        var categories= await _db.categories.ToListAsync(cancellationToken);
        var products= await _db.Products
            .Include(x=>x.ProductSpecs)
            .SingleOrDefaultAsync(s => s.Id == notification.Id, cancellationToken);
       // here the second call (products) throws the above mentioned error
       // if I only have one db call then no error throws.
        
    }

}

And also MultipleActiveResultSets is true.

Ocelot
  • 203
  • 3
  • 11
  • Is `cancellationToken` accessed anywhere not show before the `_db.categories` call? – mxmissile Nov 18 '22 at 15:14
  • It doesn't seem likely that it's related to a `SaveChangesInterceptor`, because nothing is saved there. Does the exception also occur if you don't register the interceptor? – Gert Arnold Nov 18 '22 at 15:21

0 Answers0