diff --git a/docs/en/framework/infrastructure/event-bus/distributed/index.md b/docs/en/framework/infrastructure/event-bus/distributed/index.md index 9ed2121057..d56215fa12 100644 --- a/docs/en/framework/infrastructure/event-bus/distributed/index.md +++ b/docs/en/framework/infrastructure/event-bus/distributed/index.md @@ -297,10 +297,14 @@ Configure(options => options.AutoEventSelectors.Add( type => type.Namespace.StartsWith("MyProject.") ); + + //Ignore for a single entity + options.IgnoredEventSelectors.Add(); }); ```` -* The last one provides flexibility to decide if the events should be published for the given entity type. Returns `true` to accept a `Type`. +* The `type.Namespace.StartsWith("MyProject.")` provides flexibility to decide if the events should be published for the given entity type. Returns `true` to accept a `Type`. +* The `IgnoredEventSelectors` is used to ignore the events for the specified entity types. It is useful if you enabled for all entities and want to ignore for some entities. You can add more than one selector. If one of the selectors match for an entity type, then it is selected. diff --git a/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/AbpDistributedEntityEventOptions.cs b/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/AbpDistributedEntityEventOptions.cs index 19af763c85..8109d945bc 100644 --- a/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/AbpDistributedEntityEventOptions.cs +++ b/framework/src/Volo.Abp.Ddd.Domain.Shared/Volo/Abp/Domain/Entities/Events/Distributed/AbpDistributedEntityEventOptions.cs @@ -4,11 +4,14 @@ public class AbpDistributedEntityEventOptions { public IAutoEntityDistributedEventSelectorList AutoEventSelectors { get; } + public IAutoEntityDistributedEventSelectorList IgnoredEventSelectors { get; } + public EtoMappingDictionary EtoMappings { get; set; } public AbpDistributedEntityEventOptions() { AutoEventSelectors = new AutoEntityDistributedEventSelectorList(); + IgnoredEventSelectors = new AutoEntityDistributedEventSelectorList(); EtoMappings = new EtoMappingDictionary(); } } diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs index 44eb5c058a..eb16a6910c 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs @@ -68,13 +68,9 @@ public class EntityChangeEventHelper : IEntityChangeEventHelper, ITransientDepen private bool ShouldPublishDistributedEventForEntity(object entity) { - return DistributedEntityEventOptions - .AutoEventSelectors - .IsMatch( - ProxyHelper - .UnProxy(entity) - .GetType() - ); + var entityType = ProxyHelper.UnProxy(entity).GetType(); + return !DistributedEntityEventOptions.IgnoredEventSelectors.IsMatch(entityType) && + DistributedEntityEventOptions.AutoEventSelectors.IsMatch(entityType); } public virtual void PublishEntityUpdatedEvent(object entity) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs index c98ef478d4..6af11ebeca 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Domain; +using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EntityFrameworkCore.DistributedEvents; using Volo.Abp.Modularity; using Volo.Abp.Uow.EntityFrameworkCore; @@ -28,5 +29,11 @@ public class AbpEntityFrameworkCoreModule : AbpModule context.Services.TryAddTransient(typeof(IDbContextProvider<>), typeof(UnitOfWorkDbContextProvider<>)); context.Services.AddTransient(typeof(IDbContextEventOutbox<>), typeof(DbContextEventOutbox<>)); context.Services.AddTransient(typeof(IDbContextEventInbox<>), typeof(DbContextEventInbox<>)); + + Configure(options => + { + options.IgnoredEventSelectors.Add(); + options.IgnoredEventSelectors.Add(); + }); } } diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs index 91d2808010..8e8ad345fc 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs @@ -4,6 +4,7 @@ using MongoDB.Bson; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Serializers; using Volo.Abp.Domain; +using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.Modularity; using Volo.Abp.MongoDB.DependencyInjection; @@ -48,5 +49,11 @@ public class AbpMongoDbModule : AbpModule typeof(IMongoDbContextEventInbox<>), typeof(MongoDbContextEventInbox<>) ); + + Configure(options => + { + options.IgnoredEventSelectors.Add(); + options.IgnoredEventSelectors.Add(); + }); } } diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityChangeEvents_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityChangeEvents_Tests.cs index 12b3fa01c0..36979fdd7c 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityChangeEvents_Tests.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityChangeEvents_Tests.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Domain.Entities.Events; using Volo.Abp.Domain.Entities.Events.Distributed; @@ -17,16 +18,26 @@ public abstract class EntityChangeEvents_Tests : TestAppTestBase where TStartupModule : IAbpModule { protected IRepository PersonRepository { get; } + protected ICityRepository CityRepository { get; } protected ILocalEventBus LocalEventBus { get; } protected IDistributedEventBus DistributedEventBus { get; } protected EntityChangeEvents_Tests() { PersonRepository = GetRequiredService>(); + CityRepository = GetRequiredService(); LocalEventBus = GetRequiredService(); DistributedEventBus = GetRequiredService(); } + protected override void AfterAddApplication(IServiceCollection services) + { + services.Configure(options => + { + options.IgnoredEventSelectors.Add(); + }); + } + [Fact] public async Task Complex_Event_Test() { @@ -62,7 +73,7 @@ public abstract class EntityChangeEvents_Tests : TestAppTestBase await uow.CompleteAsync(); } - + createdEventTriggered.ShouldBeTrue(); createdEtoTriggered.ShouldBeTrue(); } @@ -113,4 +124,33 @@ public abstract class EntityChangeEvents_Tests : TestAppTestBase updateEventCount.ShouldBe(1); updatedAge.ShouldBe(45); } + + [Fact] + public async Task Should_Not_Trigger_Event_If_Ignore_Event_Selector_Is_Configured() + { + var personCreatedEtoTriggered = false; + var cityCreatedEtoTriggered = false; + using (var uow = GetRequiredService().Begin()) + { + DistributedEventBus.Subscribe>(eto => + { + cityCreatedEtoTriggered = true; + return Task.CompletedTask; + }); + + DistributedEventBus.Subscribe>(eto => + { + personCreatedEtoTriggered = true; + return Task.CompletedTask; + }); + + await CityRepository.InsertAsync(new City(Guid.NewGuid(), "Istanbul")); + await PersonRepository.InsertAsync(new Person(Guid.NewGuid(), "John", 15)); + + await uow.CompleteAsync(); + } + + personCreatedEtoTriggered.ShouldBeTrue(); + cityCreatedEtoTriggered.ShouldBeFalse(); + } }