I have a project, previously ef commands such as add-migration and update-database were working correctly. But I did some things after which these commands don't work anymore.
1- Adding Resharper plugin. that even by disabling this plugin, these commands still don't work. In addition, I made a test project that with this plugin, those commands worked correctly.
2- Create a new C# library. I created a folder and built the library, but instead of being built in the folder, the library was built in the root. I deleted the folder and the library and there is no trace of this library in the sln file.
3- Update all ef libraries from version 8.0.2 to 8.0.3
In my solution, there are several C# libraries, each of which has its own DbContext (cqrs). In the main project related to Command, there is a DbContext named ContentCommandDbContext, in version 8.0.2, I created another DbContext named ContentCommandDbContextFactory, which inherits from IDesignTimeDbContextFactory and fixes errors.
The problem I have now is that every ef command that I execute in the PackageManagerConsule window does not happen after the build of the project and the program remains running in the background and does not create a script. And it remains running in the background until I restart the computer.
But when I execute commands through CLI, it is done correctly.
Does anyone know where the problem is and how can I fix it so that I can use vs 2022 as before?
-----------Update-----------
I found the problem. The problem is with the IPublishEndpoint in my custom Interceptor. When I remove the parts related to IPublishEndpoint, the commands work correctly.
Even when I create the database with CLI commands, when the program wants to save data through ef core8, the program still does not work.
public class DomainEventsDispatcherInterceptor : SaveChangesInterceptor
{
private readonly IMediator _mediator;
private readonly IPublishEndpoint _publishEndpoint;
//todo using masstransit here
public DomainEventsDispatcherInterceptor(IServiceProvider serviceProvider)
{
_publishEndpoint = serviceProvider.GetRequiredService<IPublishEndpoint>();
_mediator = serviceProvider.GetRequiredService<IMediator>();
}
public override async ValueTask<int> SavedChangesAsync(SaveChangesCompletedEventData eventData, int result,
CancellationToken cancellationToken = default)
{
var affectedRows = await base.SavedChangesAsync(eventData, result, cancellationToken);
if (affectedRows > 0)
{
var aggregateRoots =
eventData.Context?.ChangeTracker.Entries()
.Where(current => current.Entity is IAggregateRoot)
.Select(current => current.Entity as IAggregateRoot)
.ToList()
;
foreach (var aggregateRoot in aggregateRoots)
{
// Dispatch Events!
if (aggregateRoot != null)
{
foreach (var domainEvent in aggregateRoot.DomainEvents)
{
// await _mediator.Publish(domainEvent, cancellationToken);
await _publishEndpoint.Publish(domainEvent, cancellationToken); //albate domain event ehtenmalan moshkel darad bayad dar eventbus.message bashad baraye namespace ha ke dar masstransit mohem hastand
//add masstransit
}
// Clear Events!
aggregateRoot.ClearDomainEvents();
}
}
}
return affectedRows;
}
public override int SavedChanges(SaveChangesCompletedEventData eventData, int result)
{
var affectedRows = base.SavedChanges(eventData, result);
if (affectedRows > 0)
{
var aggregateRoots =
eventData.Context?.ChangeTracker.Entries()
.Where(current => current.Entity is IAggregateRoot)
.Select(current => current.Entity as IAggregateRoot)
.ToList()
;
foreach (var aggregateRoot in aggregateRoots)
{
// Dispatch Events!
if (aggregateRoot != null)
{
foreach (var domainEvent in aggregateRoot.DomainEvents)
{
//_mediator.Publish(domainEvent);
_publishEndpoint.Publish(domainEvent); //albate domain event ehtenmalan moshkel darad bayad dar eventbus.message bashad baraye namespace ha ke dar masstransit mohem hastand
}
// Clear Events!
aggregateRoot.ClearDomainEvents();
}
}
}
return affectedRows;
}
And the following code is the settings in the Program.cs file:
...
//add command dbcontext
builder.Services.AddDbContext<ContentCommandDbContext>((serviceProvider, options) =>
{
options.UseSqlServer(cnn, option =>
{
option.EnableRetryOnFailure(6);
option.MinBatchSize(1);
});
options.AddInterceptors(new IInterceptor[]
{
new DomainEventsDispatcherInterceptor(serviceProvider)
}); ;
});
//add query dbcontext
builder.Services.AddDbContext<ContentQueryDbContext>(c => c.UseSqlServer(cnn));
....
builder.Services.AddMassTransit(x =>
{
x.AddEntityFrameworkOutbox<ContentCommandDbContext>(o =>
{
o.QueryDelay = TimeSpan.FromSeconds(1);
o.UseSqlServer();
o.UseBusOutbox();
});
//The outbox can also be added to all consumers using a configure endpoints callback:
// https://masstransit.io/documentation/configuration/middleware/outbox
x.AddConfigureEndpointsCallback((context, name, cfg) =>
{
cfg.UseEntityFrameworkOutbox<ContentCommandDbContext>(context);
});
x.UsingRabbitMq((context, cfg) =>
{
cfg.Host("amqp://guest:guest@localhost:5672 ");
cfg.AutoStart = true;
cfg.ReceiveEndpoint("queue-name", c => c.ConfigureConsumers(context));
});
x.AddConsumers(typeof(CommentAddedEvent).Assembly, typeof(CommentAddedEventHandler).Assembly);
});
...
Can someone guide me, where is the problem?
I found the answer. I should have used IBus instead of IPublishEndpoint.