- fixed LowerCaseConvention null reference exceptions when key names were null (e.g. with owned types)
- fixed LambdaCommandBusExtensions return values
- fixed: FakeClock value changes must be atomic
- upgraded to EasyNetQ 7.8.0
- fixed support for multiple registered IDatabaseMigrationProvider(s)
- just bumped the version (to work around NuGet push error)
- added .NET 8.0 support with extra build targets
- EF Core 8.x for .NET 8.0 build variants
- set Hangfire JobStorage early to prevent errors when calling it before its server starts
- removed NLog dependency, logging replaced with standard Microsoft.Extensions.Logging; if you want to keep using NLog, you have to install it in your projects and set-up the adapters on your own
- added configuration options for Hangfire processing server
- Hangfire dashboard is now disabled by default
- updated NuGet metadata to use new preferred format (package icon, license expression, packaged README), added EmbedUntrackedSources
- breaking: all core packages now target .NET 6.0/7.0
- added build targets for .NET 7 with ASP.NET Core 7
- upgraded optional AutoMapper extension to v12.0
- upgraded to Entity Framework Core 7.0
- in EF Core, when synchronously projecting multiple times in a single tx (e.g. because projector itself publishes events), do not project the already projected events again
- CRUD aggregate store now correctly deletes aggregates when the action also triggers the removal of other related entities
- added StoreDate metadata to events published by CRUD aggregates
- CRUD aggregate store now throws exception / returns null for Get*/Find* methods when the aggregate is pending deletion
- fixed IDatabaseInitializer sorting with InitializeAfterAttribute (was only comparing neighbors) & added support for transitive dependencies
- Now targeting .NET 6.0 and .NET Standard 2.0 (dropping support for .NET Framework, .NET 3.1 and .NET Standard 2.0)
- Upgraded to ASP.NET Core 6.0, Entity Framework Core 6.0, AutoMapper 11
- EasyNetQ custom service registration
- fixed BufferedNotificationStore creating the same buffer multiple times
- fixed InMemoryCrudRepository returning non-saved entries & added tests
- breaking change (notifications extension): notification buffers, pipeline and governors are now identified using arbitrary string names instead of GUIDs for more flexibility
- returning null values in JsonMetadata
- Fixed NuGet release
- CrudEntityEventToPocoProjector now sets read model TenantId from metadata of first event if no TenantAggregateRootCreated is published (e.g. for non-event sourced entities)
- ProjectionEventListener now runs the async projections with correct tenant context from the events
- MetadataExtensions.GetPublishDate and GetStoreDate now return a nullable value
- EasyNetQ subscription AddType configuration should provide default empty configuration callback when passed null
- EasyNetQ subscriptions can now be registered as blocking (i.e. processed sequentially, waiting until the event listeners complete before processing next message)
- major version updates for dependencies: AutoMapper 10, EasyNetQ 6
- fixed LambdaCommandBusExtensions.SendLambdaCommandAsync overloads that did not return value, added 'Async' suffix to method name for consistency
- added SendLambdaCommand extension: easily executes specified lambda like it was performed by any regular command handler
- by default, event source and event queue catch-ups now don't block application startup until finished (IAsyncEventPipelineConfiguration.WaitForEventCatchUpsUponStartup)
- database migration hooks - can now listen to events like DatabaseMigrationBeforeAppliedEvent, DatabaseMigrationAppliedEvent and DatabaseMigrationsCommittedEvent
- transactionMode for database migrations (isolated, without) for overriding their transaction behavior
- ExternalEventSourceCatchUp should dispatch messages with metadata mapped from the event record (e.g. ID)
- async events might occasionally have gotten enqueued twice during EF Core's coordinated transaction
- support for generic commands (still without automatic discovery of generic command handlers, though, needs to register manually)
- database migrations are run inside a unit of work when using EF Core and EF6 providers
- EF Core/EF6 migration providers no longer create database upon startup
- renamed lifecycle hook interfaces (IApplicationStartedListener, IApplicationStoppingListener) and added new IApplicationStartingListener hook
- better performance when enqueueing async events & for EFCoreCrudRepository.IsAttached
- added support for event serializer customization
- external events and events published by non-event sourced aggregates are not stored to DB if not dispatched to any async event queues (no need to store them then)
- UseAllEFCoreInfrastructure/UseAllEF6Infrastructure did not run advancedAction, if supplied
- breaking change: BasicEventMetadataNames moved to Revo.Core.Events
- manually published events no longer require explicitly set event message ID
- added option to rerun repeatable database migrations when their dependencies get updated (RerunRepeatableMigrationsOnDependencyUpdate - default to true)
- JobRunner was causing AmbiguousMatchException when a job handler class implemented more IJobHandler interfaces
- missing IQueryTranslationPlugin in EF Core's internal DI container
- custom query provider + helpers in EF Core provider for easier query authorization (default enabled by EnableCustomQueryProvider) with AuthorizationQueryableExtensions
- support for custom EF Core query translation plugins (IQueryTranslationPlugin)
- IEFCoreReadRepository.FromSqlInterpolated and FromSqlRaw (which apply repository filters, unlike existing IEFCoreDatabaseAccess methods)
- IEntityQueryFilter.FilterAsync overload without command (just takes the current one)
- IEntityQueryFilter.FilterAsync filter is now generic to enable easier filtering for derived entity types
- breaking change: TenantRepositoryFilter gets injected always, but uses now only Lazy - fixes issue when first request didn't have the filter applied (hint: use ExcludeFilters method when implementing a custom ITenantProvider)
- Permission constructor now correctly accepts objects as contextId and resourceId (in accordance with change from 1.18.0)
- fixed publishing of NuGet package symbols: now using separate snupkg for symbols
- support for .NET 5.0, ASP.NET Core 5.0 and EF Core 5.0 (supporting both 3.1 and 5.0 versions now)
- Permission.ContextId and ResourceId can now be any objects
- updated minor version for EF Core 3.1.x
- updated RavenDB.Client to 5.0.4, Revo.RavenDB now only requires netstandard2.0
- Rebus:
- using manual configuration instead of XML now
- updated dependency to 5.0.4
- Revo.Rebus now only requires netstandard2.0
- dropping support for legacy ASP.NET platform (.NET 4.7)
- removed core dependency on AutoMapper
- the functionality of automatic registration of profiles got separated into new Revo.Extensions.AutoMapper package
- updated to AutoMapper 9.0
- Apply methods inherited in EntityEventProjector no longer get called multiple times
- catching ReflectionTypeLoadException exceptions in TypeExplorer
- improved multi-tenancy configuration
- major refactoring of command bus internals:
- support for multiple command buses (local, remote...)
- routing commands to buses with command gateway
- overhauled command pipeline based on new and more flexible command bus middlewares
- CommandExecutionOptions that can change the tenant context to run the command in and other options
- AsyncEventListenerBindingExtensions for easier async event listener registration
- convenience methods IReadRepository.GetManyAsync and IReadRepository.FindManyAsync using Guid IDs
- added PerAggregateAsyncEventSequencer and PerTenantAsyncEventSequencer for common sequencer scenarios
- added IDatabaseInitializerLoader.EnsureDatabaseInitialized
- breaking change: null tenants now cannot access other tenant's data by default (can be changed by configuration)
- breaking change: ITenant moved from Revo.Domain to Revo.Core
- simplified security (IUserManager replaced with Revo.Core.Security.IClaimsPrincipalResolver, disabling null implementations can now be done with CoreConfigurationSection.Security.UseNullSecurityModule)
- Permission now contains only PermissionTypeId instead of PermissionType
- Repository can now be instantiated even without any active UnitOfWork
- updated to (ASP).NET Core 3.1
- ASP.NET Core provider's RevoStartup class now only calls AddMvcCore() instead of AddMvc(), you have to add other parts yourself in ConfigureServices(...) if you want them
- Revo.AspNetCore.Security.ISignInManager removed, use IUserContext instead
- AuthorizePermissionsAttribute for old ASP.NET 4 removed (inconsistent with the rest of the framework)
- IDatabaseMigrationExecutionOptions.MigrateOnlySpecifiedModules can now be specified using wildcards
- database migrations: doesn't throw anymore if there is no migration for specified version, but DB is already up-to-date
- database migrations: now throws when updating to 'latest' version, but no migrations are found
- IReadRepository.GetManyAsync and FindManyAsync
- fixed appending events to event store (wrong expected event number)
- event upgrade support - just implement IEventUpgrade in your code (auto discovery) and Revo upgrades the event streams on-the-fly upon loading the aggregates
- event version parsed from types whose name ends with V letter without number no longer recognized as versioned name
- EventSourcedAggregateRoot.Commit increases Version by 1 (previously by event count)
- EntityEventToPocoProjector uses AggregateVersion instead of StreamSequenceNumber event metadata for read model versioning
- removed APNS and FCM (push notification) channel support from Revo.Extensions.Notifications using obsolete PushSharp library
- now it's possible to specify FileSqlDatabaseMigration version in its headers
- database migrations - new own system for managing database schema version migrations (incl. module dependencies)
- standalone database migration tool Revo.Tools.DatabaseMigrator (also invokable as global .NET Core tool revo-dbmigrate)
- support for SQLite in EF Core infrastructure implementation (event store, async event queues, etc.)
- events are now correctly marked as dispatched even when there are no listeners for them
- fixed missing IExternalEventStore registration for EF6 provider
- not resetting DbContexts after EFCoreCoordinatedTransaction finishes
- Entity Framework 6 provider updated to EF6.3 version and is now targeting both net472 and netstandard2.1
- Revo.Extensions.Notifications and Revo.Extensions.History now need to be explicitly registered in Revo configuration using AddHistoryExtension and AddNotificationsExtension
- removed IRepository.SaveChangesAsync to avoid confusion - it doesn't work well in certain situations (e.g. with EF Core provider) and IUnitOfWork.CommitAsync should be used instead
- NLog updated to 4.6.7
- new BaseTypeAttribute for EF Core mapping - overrides the mapped entity base type
- upgraded to ASP.NET Core 3.0 and Entity Framework Core 3.0
- ReadModelForEntityAttribute no longer overrides mapped table name (leaves default)
- dropped OData out-of-the-box integration on ASP.NET & ASP.NET Core platforms altogether (OData is not supported on ASP.NET Core 3.0 now), you have to integrate it by yourself now
- IRepository.FindManyAsync and GetManyAsync with optimized batch-loading of event sourced aggregates
- IRepository.FindAllAsync now returns an array instead of IList
- improved StaticClassifierDatabaseInitializer, now also supporting event sourced aggregates
- Cake script now uses VS2019 build toolset
- EF Core's PrefixConvention now correctly prefixes columns defined in abstract classes annotated with TablePrefixAttribute
- IAsyncQueryableResolver.AnyAsync
- injection support for SignalR hubs in Revo.AspNetCore
- IEventNumberVersioned and EventEntityReadModel for read models with additional arbitrary versioning (concurrency control)
- now possible to configure ODataQuerySettings for EFCoreQueryableToODataResultConverter
- removed IEventSourcedAggregateRoot constraints from EF Core and EF6 projectors (now can be any IAggregateRoot)
- CrudAggregateStore now automatically removes entities that have been marked with IsDeleted
- FakeRepository now correctly removes entites that have been flagged as IsDeleted
- new Revo.EasyNetQ module for simple integrations with RabbitMQ
- default EventSerializer and NotificationSerializer now use the same JSON serializer settings
- EF Core's PrefixConvention with deeper inheritance hierarchies
- EF Core sync projectors are invoked not invoked multiple times with the same events
- obsolete Globalization stuff (messages, locales, translatable entities, ASP.NET localization helpers...)
- new default in-memory job scheduler
- FakeClock now uses AsyncLocal instead of ThreadLocal
- refactored Revo.Extensions.Notifications for .NET Core compatibility and better configuration
- projects upgraded to .NET Core 2.2, ASP.NET Core 2.2 and Entity Framework Core 2.2
- automatic event projector discovery and registration (now enabled by default)
- event publishing for non-event sourced entities (not transactionally safe and not saving to event store yet, though, so beware)
- coordinated UoW transaction for EF Core including synchronous projections, publishing events from projections and fast event queue dispatching
- EFCoreInMemoryCrudRepository and EFCoreInMemoryDatabaseAccess
- recurring job scheduling support
- optimized event queue dispatching for big amounts of queues
- ODataAsyncResultFilter.DefaultConverter now returns correct counts
- fixed BasicDomainModelConvention when using inheritance including abstract types
- fixed binding of Hangfire and infrastructure configuration sections, added more options
- #1 ASP.NET Core support - platform implementation, i.e. user context, security, DI, OData, etc.
- #2, #3 EF Core support - data access & infrastructure (async events, sagas, projections...)
- Throttling async event processing to minimize the amount of running tasks and open DB connections (when running event queue catch-ups during app start-up and pseudo-synchronously processing events after a request; see IAsyncEventPipelineConfiguration)
- flattened and simplified package structure (now provider-centric) - vendor-specific modules were moved
to Providers directory and some of them were merged/renamed:
- Revo.Platforms.AspNet → Revo.AspNet
- Revo.DataAccess.EF6 and Revo.Infrastructure.EF6 → Revo.EF6
- Revo.DataAccess.RavenDB → Revo.RavenDB
- Revo.Integrations.Rebus → Revo.Rebus
- improved AsyncEventWorker concurrency - framework did not prevent multiple workers from parallel processing of one async event queue, causing occasional (e.g. when under heavy load) concurrency exceptions (which are eventually handled by an automatic retry); now allowing only one active worker per a queue in an application instance
- Ninject binding extensions InRequestOrJobScope is now two separate methods with corresponding fallbacks in order - InTaskScope (mostly preferred) and InRequestScope
- IAutoMapperDefinition - removed as obsolete and replaced with AutoMapper's own profiles (auto-discovered again)
- removed implicit ASP.NET Web API configuration - i.e. default OData and serializer settings
- TokenValidator - removed as obsolete
- (Tenant)ContextSequence - removed (possibly to be reimplemented later)
- CRUD repositories now correctly wrap their concurrency exceptions as OptimisticConcurrencyException
- objects from DI container are now deterministically disposed at the end of tasks run within a context (also reducing amount of unused open DB connection)
- Hangfire job task context disposal now correctly awaits the command to finish
- EF6SagaMetadataRepository bug not including the keys in a query
- EF6 saga keys not being reloaded correctly due to JSON serialization changing dictionary key character cases
- ExecuteCommandJob is now resolved correctly by Hangfire
- (I)UserPermissionAuthorizer for manual and more fine-grained user action authorization
- EF6/EntityEventProjector for more arbitrary projections
- framework configuration - framework and its module parameters now need to be programmatically configured and set-up using the newly introduced RevoConfiguration
- PermissionAuthorizer renamed to PermissionAuthorizationMatcher
- Default ASP.NET Web API JSON ContractResolver switched to DefaultContractResolver with CamelCaseNamingStrategy from CamelCasePropertyNamesContractResolver (matches default ASP.NET Core behavior and does not change dictionary key character cases)
- Hangfire integration for background job processing got its own Revo.Infrastructure.Hangfire package
- First public version released.