├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── config.yml
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── pr-checks.yml
├── .gitignore
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SUPPORT.md
├── Samples
└── Metadata
│ ├── MetadataSamples.sln
│ ├── PersistedMetadata
│ ├── MessageWindow.Designer.cs
│ ├── MessageWindow.cs
│ ├── Messages.cs
│ ├── PersistedMetadata.csproj
│ └── Program.cs
│ └── SimpleMetadata
│ ├── MessageWindow.Designer.cs
│ ├── MessageWindow.cs
│ ├── Messages.cs
│ ├── Program.cs
│ └── SimpleMetadata.csproj
├── build
├── ReactiveDomain.Policy.props
├── ReactiveDomain.Testing.props
├── ReactiveDomain.UI.Testing.props
├── ReactiveDomain.UI.props
└── ReactiveDomain.props
├── package.bat
├── publish.bat
├── src
├── .editorconfig
├── .nuget
│ └── NuGet.exe
├── Dependency.Versions.props
├── PolicyTool.sln
├── ReactiveDomain.Core
│ ├── Audit
│ │ └── AuditRecord.cs
│ ├── IEventSource.cs
│ ├── IMetadata.cs
│ ├── IMetadataSource.cs
│ ├── Logging
│ │ ├── ConsoleLogger.cs
│ │ ├── ILogger.cs
│ │ ├── LazyLogger.cs
│ │ ├── LogManager.cs
│ │ └── NullLogger.cs
│ ├── Messaging
│ │ └── Json.cs
│ ├── Metadata.cs
│ ├── MetadatumNotFoundException.cs
│ ├── ReactiveDomain.Core.csproj
│ └── Util
│ │ ├── Application.cs
│ │ ├── BytesFormatter.cs
│ │ ├── CustomConfigLoader.cs
│ │ ├── Disposer.cs
│ │ ├── Empty.cs
│ │ ├── Ensure.cs
│ │ ├── EnumerableExtensions.cs
│ │ ├── FileStreamExtensions.cs
│ │ ├── FileUtils.cs
│ │ ├── FluentExtensions.cs
│ │ ├── Helper.cs
│ │ ├── HostName.cs
│ │ ├── IPEndPointComparer.cs
│ │ ├── IpEndPointExtensions.cs
│ │ ├── MD5Hash.cs
│ │ ├── OS.cs
│ │ ├── ShellExecutor.cs
│ │ ├── StringExtensions.cs
│ │ └── Unit.cs
├── ReactiveDomain.Debug.nuspec
├── ReactiveDomain.Foundation.Tests
│ ├── Domain
│ │ ├── AggregateRootEntityTests.cs
│ │ ├── CapturingRoute.cs
│ │ ├── CorrelatedAggregate.cs
│ │ ├── MetadataTests.cs
│ │ ├── MetadatumTests.cs
│ │ ├── with_correlated_aggregate.cs
│ │ ├── with_correlated_repository.cs
│ │ └── with_repository.cs
│ ├── EmbeddedStreamStoreConnectionCollection.cs
│ ├── Logging
│ │ ├── when_commands_are_fired.cs
│ │ ├── when_events_are_published.cs
│ │ ├── when_logging_disabled_and_commands_are_fired.cs
│ │ ├── when_logging_disabled_and_events_are_published.cs
│ │ ├── when_logging_disabled_and_mixed_messages_are_published.cs
│ │ ├── when_logging_high_volume_message_traffic.cs
│ │ ├── when_mixed_messages_are_published.cs
│ │ ├── when_toggling_logging.cs
│ │ ├── when_toggling_logging_from_disabled.cs
│ │ ├── with_message_logging_disabled.cs
│ │ └── with_message_logging_enabled.cs
│ ├── PrefixedCamelCaseStreamNameBuilderTests.cs
│ ├── ReactiveDomain.Foundation.Tests.csproj
│ ├── StreamListenerTests
│ │ ├── Common
│ │ │ ├── CommonHelpers.cs
│ │ │ └── TestStreamNameBuilder.cs
│ │ ├── when_using_listener_start_with_aggregate_and_guid.cs
│ │ ├── when_using_listener_start_with_category_aggregate.cs
│ │ ├── when_using_listener_start_with_custom_stream_not_synched.cs
│ │ ├── when_using_listener_start_with_custom_stream_synched.cs
│ │ ├── when_using_listener_start_with_custom_stream_synched_bus.cs
│ │ ├── when_using_listener_start_with_event_type.cs
│ │ └── when_using_listener_start_with_future_stream.cs
│ ├── can_serialize_correlated_messages.cs
│ ├── when_serializing_with_json_message_serializer.cs
│ ├── when_using_caching_repository.cs
│ ├── when_using_correlated_repository.cs
│ ├── when_using_read_model_base.cs
│ ├── when_using_read_model_base_with_reader.cs
│ └── when_using_snapshot_read_model.cs
├── ReactiveDomain.Foundation
│ ├── BootStrap.cs
│ ├── ConfiguredConnection.cs
│ ├── Domain
│ │ ├── AggregateRoot.cs
│ │ ├── ChildEntity.cs
│ │ ├── EventDrivenStateMachine.cs
│ │ ├── EventRecorder.cs
│ │ ├── EventRouter.cs
│ │ ├── ICorrelatedEventSource.cs
│ │ ├── ISnapshotSource.cs
│ │ ├── IdempotentEventIdGenerator.cs
│ │ ├── NameBasedGuidGenerator.cs
│ │ └── ProcessManager.cs
│ ├── ICatchupStreamSubscriber.cs
│ ├── IConfiguredConnection.cs
│ ├── ICorrelatedRepository.cs
│ ├── IListener.cs
│ ├── IRepository.cs
│ ├── IStreamNameBuilder.cs
│ ├── IStreamReader.cs
│ ├── PrefixedCamelCaseStreamNameBuilder.cs
│ ├── ReactiveDomain.Foundation.csproj
│ ├── RepositoryExtensions.cs
│ ├── StreamStore
│ │ ├── AggregateDeletedException.cs
│ │ ├── AggregateNotFoundException.cs
│ │ ├── AggregateVersionException.cs
│ │ ├── CachingRepository.cs
│ │ ├── CommonMetadata.cs
│ │ ├── ContractResolver.cs
│ │ ├── CorrelatedStreamStoreRepository.cs
│ │ ├── IAggregateCache.cs
│ │ ├── IEventSerializer.cs
│ │ ├── JsonMessageSerializer.cs
│ │ ├── JsonMessageSerializerSettings.cs
│ │ ├── OptimisticCacheRepository.cs
│ │ ├── QueuedStreamListener.cs
│ │ ├── ReadModelBase.cs
│ │ ├── ReadModelProperty.cs
│ │ ├── ReadModelState.cs
│ │ ├── ReadThroughAggregateCache.cs
│ │ ├── SnapshotReadModel.cs
│ │ ├── StreamListener.cs
│ │ ├── StreamReader.cs
│ │ ├── StreamStoreMsgs.cs
│ │ └── StreamStoreRepository.cs
│ └── TransientSubscriber.cs
├── ReactiveDomain.IdentityStorage.Tests
│ ├── ClientStoreTests.cs
│ ├── MockPrincipal.cs
│ ├── ReactiveDomain.IdentityStorage.Tests.csproj
│ ├── ResourceStoreTests.cs
│ ├── SubjectAggTests.cs
│ ├── SubjectRmTests.cs
│ ├── TestMessages.cs
│ ├── UserAggregateTests.cs
│ ├── UserServiceTests.cs
│ ├── UserStoreTests.cs
│ └── UsersRMTests.cs
├── ReactiveDomain.IdentityStorage
│ ├── Domain
│ │ ├── Client.cs
│ │ ├── Subject.cs
│ │ └── User.cs
│ ├── Messages
│ │ ├── ClientMsgs.cs
│ │ ├── SubjectMsgs.cs
│ │ └── UserMsgs.cs
│ ├── ReactiveDomain.IdentityStorage.csproj
│ ├── ReadModels
│ │ ├── PrincipalWrapper.cs
│ │ ├── SubjectsRm.cs
│ │ ├── UserDTO.cs
│ │ └── UsersRm.cs
│ ├── Services
│ │ ├── ActiveDirectoryUserSearch.cs
│ │ ├── ClientStore.cs
│ │ ├── ClientSvc.cs
│ │ ├── ResourcesStore.cs
│ │ ├── UserStore.cs
│ │ ├── UserSvc.cs
│ │ └── UserValidation.cs
│ ├── SubjectExceptions.cs
│ └── UserExceptions.cs
├── ReactiveDomain.Messaging.Tests
│ ├── LaterServiceTests.cs
│ ├── MessageExtensionsTests.cs
│ ├── ReactiveDomain.Messaging.Tests.csproj
│ ├── RemoteBusFixture.cs
│ ├── Subscribers
│ │ └── QueuedSubscriber
│ │ │ ├── can_handle_multiple_publisher_threads_queued.cs
│ │ │ ├── can_handle_ordered_queued_messages.cs
│ │ │ └── can_unsubscribe_queued_messages.cs
│ ├── TimePositionTests.cs
│ ├── can_cancel_commands_via_cancellation_token.cs
│ ├── when_connecting_buses.cs
│ ├── when_creating_a_message.cs
│ ├── when_ensuring_values.cs
│ ├── when_publishing_a_message.cs
│ ├── when_rebuilding_message_hierarchy.cs
│ ├── when_sending_commands.cs
│ ├── when_sending_commands_via_single_queued_dispatcher.cs
│ ├── when_sending_concurrent_commands.cs
│ ├── when_sending_remote_handled_commands.cs
│ ├── when_serializing_commands.cs
│ └── when_serializing_ids.cs
├── ReactiveDomain.Messaging
│ ├── BootStrap.cs
│ ├── Bus
│ │ ├── AdHocCommandHandler.cs
│ │ ├── AdHocHandler.cs
│ │ ├── AdHocTypedCommandHandler.cs
│ │ ├── BusConnector.cs
│ │ ├── CommandException.cs
│ │ ├── CommandHandler.cs
│ │ ├── CommandManager.cs
│ │ ├── CommandTracker.cs
│ │ ├── DelaySendEnvelope.cs
│ │ ├── Dispatcher.cs
│ │ ├── DynamicHandler.cs
│ │ ├── ExistingHandlerException.cs
│ │ ├── HandleExtensions.cs
│ │ ├── IApply.cs
│ │ ├── IBus.cs
│ │ ├── ICommandBus.cs
│ │ ├── ICommandPublisher.cs
│ │ ├── ICommandSubscriber.cs
│ │ ├── IDispatcher.cs
│ │ ├── IHandle.cs
│ │ ├── IHandleCommand.cs
│ │ ├── IMonitoredQueue.cs
│ │ ├── IPublisher.cs
│ │ ├── IQueuedHandler.cs
│ │ ├── ISubscriber.cs
│ │ ├── IdempotentHandler.cs
│ │ ├── InMemoryBus.cs
│ │ ├── LaterService.cs
│ │ ├── MessageHandler.cs
│ │ ├── MultiQueuedHandler.cs
│ │ ├── MultiQueuedPublisher.cs
│ │ ├── NarrowingHandler.cs
│ │ ├── NullBus.cs
│ │ ├── NullableBus.cs
│ │ ├── QueueMonitor.cs
│ │ ├── QueueStatsCollector.cs
│ │ ├── QueuedHandler.cs
│ │ ├── QueuedHandlerDiscarding.cs
│ │ ├── QueuedSubscriber.cs
│ │ ├── TimePosition.cs
│ │ ├── TimeSource.cs
│ │ └── WideningHandler.cs
│ ├── CallbackEnvelope.cs
│ ├── Forwarder.cs
│ ├── IEnvelope.cs
│ ├── MessageBuilder.cs
│ ├── MessageHierarchy.cs
│ ├── Messages
│ │ ├── Command.cs
│ │ ├── CommandResponse.cs
│ │ ├── CorrelatedRoot.cs
│ │ ├── CorrelationSource.cs
│ │ ├── Event.cs
│ │ ├── IChainedMessage.cs
│ │ ├── ICommand.cs
│ │ ├── ICommandResponse.cs
│ │ ├── ICorrelatedMessage.cs
│ │ ├── IEvent.cs
│ │ ├── IMessage.cs
│ │ ├── IQueueAffineMessage.cs
│ │ ├── Message.cs
│ │ └── MessageExtensions.cs
│ ├── Monitoring
│ │ ├── Stats
│ │ │ ├── DiskIo.cs
│ │ │ ├── GcStats.cs
│ │ │ ├── QueueStats.cs
│ │ │ ├── StatMetadata.cs
│ │ │ └── StatsContainer.cs
│ │ └── Utils
│ │ │ ├── PerfCounterHelper.cs
│ │ │ └── StatsCsvEncoder.cs
│ ├── NLog.xsd
│ ├── NoopEnvelope.cs
│ ├── PriorityQueue.cs
│ ├── PublishEnvelope.cs
│ ├── ReactiveDomain.Messaging.csproj
│ ├── RequestResponseDispatcher.cs
│ ├── SendToThisEnvelope.cs
│ └── TimeoutService.cs
├── ReactiveDomain.Persistence
│ ├── CatchupSubscriptionSettings.cs
│ ├── ClientConnectionEventArgs.cs
│ ├── Consts.cs
│ ├── EventData.cs
│ ├── EventReadResult.cs
│ ├── EventStore
│ │ ├── EsdbConfig.cs
│ │ ├── EventStoreConnectionManager.cs
│ │ ├── EventStoreConnectionWrapper.cs
│ │ └── EventStoreLauncher.cs
│ ├── EventStoreCatchUpSubscription.cs
│ ├── EventStoreStreamCatchUpSubscription.cs
│ ├── ExpectedVersion.cs
│ ├── IStreamStoreConnection.cs
│ ├── Position.cs
│ ├── ProjectedEvent.cs
│ ├── ReactiveDomain.Persistence.csproj
│ ├── ReadDirection.cs
│ ├── RecordedEvent.cs
│ ├── ScopedSerialization
│ │ ├── IMessageDeserializer.cs
│ │ ├── IMessageSerializer.cs
│ │ ├── ISnapshotDeserializer.cs
│ │ ├── ISnapshotSerializer.cs
│ │ ├── Serialization.cs
│ │ ├── SerializationPair.cs
│ │ ├── SerializationRegistry.cs
│ │ ├── SerializationRegistryMessageExtensions.cs
│ │ ├── SerializationRegistrySnapshotExtensions.cs
│ │ ├── SerializedMessage.cs
│ │ ├── Snapshot.cs
│ │ ├── StorableMessage.cs
│ │ └── StreamStoreReadResult.cs
│ ├── StreamEventsSlice.cs
│ ├── StreamName.cs
│ ├── StreamNameConversions.cs
│ ├── StreamNameConverter.cs
│ ├── StreamPosition.cs
│ ├── StreamStoreConnectionException.cs
│ ├── StreamSubscription.cs
│ ├── SubscriptionDropReason.cs
│ ├── UnknownTypeException.cs
│ ├── UserCredentials.cs
│ └── WriteResult.cs
├── ReactiveDomain.Policy.Debug.nuspec
├── ReactiveDomain.Policy.Tests
│ ├── GlobalSuppressions.cs
│ ├── PolicyMapTest.cs
│ ├── PolicyTests.cs
│ └── ReactiveDomain.Policy.Tests.csproj
├── ReactiveDomain.Policy.nuspec
├── ReactiveDomain.Policy.targets
├── ReactiveDomain.Policy
│ ├── AuthorizationException.cs
│ ├── Permission.cs
│ ├── Permissions.cs
│ ├── Policy.cs
│ ├── PolicyDTO.cs
│ ├── PolicyDispatcher.cs
│ ├── ReactiveDomain.Policy.csproj
│ ├── Role.cs
│ ├── UserDetails.cs
│ └── UserPolicy.cs
├── ReactiveDomain.PolicyStorage.Tests
│ ├── ApplicationAggregateTests.cs
│ ├── ApplicationServiceTests.cs
│ ├── ExternalProviderAggregateTests.cs
│ ├── Helpers
│ │ └── TestMessages.cs
│ ├── ReactiveDomain.PolicyStorage.Tests.csproj
│ ├── RoleAggregateTests.cs
│ ├── RoleServiceTests.cs
│ ├── UserEntitlementRMTests.cs
│ └── with_policy_user.cs
├── ReactiveDomain.PolicyStorage
│ ├── Domain
│ │ ├── PolicyUser.cs
│ │ ├── SecuredApplication.cs
│ │ └── SecurityPolicy.cs
│ ├── Messages
│ │ ├── ApplicationMsgs.cs
│ │ └── PolicyUserMsgs.cs
│ ├── ReactiveDomain.PolicyStorage.csproj
│ ├── ReadModels
│ │ ├── ApplicationDTO.cs
│ │ ├── ApplicationRm.cs
│ │ ├── FilteredPoliciesRM.cs
│ │ ├── PolicyDTO.cs
│ │ ├── PolicyUserDTO.cs
│ │ ├── PolicyUserRm.cs
│ │ ├── ReadModelHelper.cs
│ │ └── RoleDTO.cs
│ └── Services
│ │ ├── ApplicationSvc.cs
│ │ ├── PolicyExceptions.cs
│ │ └── PolicySvc.cs
├── ReactiveDomain.PolicyTool
│ ├── Program.cs
│ ├── Properties
│ │ ├── PublishProfiles
│ │ │ └── FolderProfile.pubxml
│ │ └── launchSettings.json
│ ├── ReactiveDomain.PolicyTool.csproj
│ └── es_settings.json
├── ReactiveDomain.Testing.Debug.nuspec
├── ReactiveDomain.Testing.nuspec
├── ReactiveDomain.Testing
│ ├── AssertEx.cs
│ ├── ConnectionUtil.cs
│ ├── DispatcherUtil.cs
│ ├── Domain
│ │ ├── Catch.cs
│ │ ├── ExpectEventsScenario.cs
│ │ ├── ExpectEventsScenarioPassed.cs
│ │ ├── ExpectExceptionScenario.cs
│ │ ├── ExpectExceptionScenarioPassed.cs
│ │ ├── IExpectEventsScenarioBuilder.cs
│ │ ├── IExpectExceptionScenarioBuilder.cs
│ │ ├── IScenarioGivenNoneStateBuilder.cs
│ │ ├── IScenarioGivenStateBuilder.cs
│ │ ├── IScenarioInitialStateBuilder.cs
│ │ ├── IScenarioThenNoneStateBuilder.cs
│ │ ├── IScenarioThenStateBuilder.cs
│ │ ├── IScenarioThrowsStateBuilder.cs
│ │ ├── IScenarioWhenStateBuilder.cs
│ │ ├── Scenario.cs
│ │ ├── ScenarioExpectedEventsButRecordedOtherEvents.cs
│ │ ├── ScenarioExpectedEventsButThrewException.cs
│ │ ├── ScenarioExpectedExceptionButRecordedEvents.cs
│ │ ├── ScenarioExpectedExceptionButThrewNoException.cs
│ │ ├── ScenarioExpectedExceptionButThrewOtherException.cs
│ │ └── ScenarioExtensions.cs
│ ├── EventStore
│ │ ├── EmbeddedStreamStoreConnectionCollection.cs
│ │ ├── EventStoreRepositoryIntegrationTests.cs
│ │ ├── MockStreamStoreConnection.cs
│ │ ├── MockStreamStoreConnectionTests.cs
│ │ ├── StreamReaderTests.cs
│ │ ├── StreamStoreConnectionFixture.cs
│ │ ├── StreamStoreReadTests.cs
│ │ └── StreamStoreSubscriptionTests.cs
│ ├── Foundation
│ │ ├── TestAggregate.cs
│ │ ├── TestAggregateCreated.cs
│ │ ├── TestAggregateMessages.cs
│ │ ├── TestWoftamAggregate.cs
│ │ └── WoftamEvent.cs
│ ├── Messaging
│ │ ├── ConcurrentMessageQueue.cs
│ │ ├── MessageComparer.cs
│ │ ├── TestCommandHandler.cs
│ │ ├── TestCommandSubscriber.cs
│ │ ├── TestCommands.cs
│ │ ├── TestEvents.cs
│ │ ├── TestInheritedMessageSubscriber.cs
│ │ ├── TestMessageHierarchy.cs
│ │ ├── TestMessageSubscriber.cs
│ │ ├── TestMessages.cs
│ │ └── TestTimeSource.cs
│ ├── ReactiveDomain.Testing.csproj
│ ├── ReactiveDomain.Testing.csproj.DotSettings
│ ├── Specifications
│ │ ├── DispatcherSpecification.cs
│ │ ├── MockRepositorySpecification.cs
│ │ ├── MockRepositoryTests.cs
│ │ ├── NullComfiguredConnection.cs
│ │ ├── NullConnection.cs
│ │ ├── NullListener.cs
│ │ ├── NullReader.cs
│ │ ├── NullRepository.cs
│ │ ├── ReadModelTestSpecification.cs
│ │ ├── TestQueue.cs
│ │ └── TestQueueTests.cs
│ ├── TestPublisher.cs
│ └── TestVisibilityHelpers.cs
├── ReactiveDomain.Tools
│ ├── EventTransformer
│ │ ├── DummyEventTransformer.cs
│ │ ├── EventTransformer.csproj
│ │ └── TransformerFactory.cs
│ └── Shovel
│ │ ├── App.config
│ │ ├── Bootstrap.cs
│ │ ├── EventShovel.cs
│ │ ├── EventShovelConfig.cs
│ │ ├── IEventTransformer.cs
│ │ ├── Program.cs
│ │ ├── Shovel.csproj
│ │ └── Shovel.sln
├── ReactiveDomain.Transport.Tests
│ ├── MockTcpConnection.cs
│ ├── ReactiveDomain.Transport.Tests.csproj
│ ├── TcpBusClientSideTests.cs
│ ├── TcpBusServerSideTests.cs
│ └── can_serialize_messages.cs
├── ReactiveDomain.Transport
│ ├── BufferManagement
│ │ ├── BufferManager.cs
│ │ ├── BufferPool.cs
│ │ ├── BufferPoolStream.cs
│ │ ├── UnableToAllocateBufferException.cs
│ │ └── UnableToCreateMemoryException.cs
│ ├── Formatting
│ │ ├── FormatterBase.cs
│ │ ├── IMessageFormatter.cs
│ │ └── RawMessageFormatter.cs
│ ├── Framing
│ │ ├── IMessageFramer.cs
│ │ ├── LengthPrefixMessageFramer.cs
│ │ ├── LengthPrefixMessageFramerWithBufferPool.cs
│ │ ├── PackageFramingException.cs
│ │ └── StxEtxMessageFramer.cs
│ ├── IMonitoredTcpConnection.cs
│ ├── ITcpConnection.cs
│ ├── Locks
│ │ └── SpinLock2.cs
│ ├── ReactiveDomain.Transport.csproj
│ ├── Serialization
│ │ ├── IMessageSerializer.cs
│ │ ├── SimpleJsonSerializer.cs
│ │ └── TcpMessageEncoder.cs
│ ├── SocketArgsPool.cs
│ ├── SystemData
│ │ ├── InspectionDecision.cs
│ │ ├── InspectionResult.cs
│ │ ├── TcpCommand.cs
│ │ ├── TcpPackage.cs
│ │ └── UserCredentials.cs
│ ├── TcpBus.cs
│ ├── TcpBusClientSide.cs
│ ├── TcpBusServerSide.cs
│ ├── TcpClientConnector.cs
│ ├── TcpConfiguration.cs
│ ├── TcpConnection.cs
│ ├── TcpConnectionBase.cs
│ ├── TcpConnectionLockless.cs
│ ├── TcpConnectionMonitor.cs
│ ├── TcpConnectionSsl.cs
│ ├── TcpInboundMessageHandler.cs
│ ├── TcpOutboundMessageHandler.cs
│ ├── TcpServerListener.cs
│ ├── TcpStats.cs
│ ├── TcpTypedConnection.cs
│ └── Util
│ │ ├── IPEndPointComparer.cs
│ │ └── IpEndPointExtensions.cs
├── ReactiveDomain.nuspec
├── ReactiveDomain.sln
├── ReactiveDomain.sln.DotSettings
├── Versions
│ └── latest.txt
├── build.props
├── ci.build.imports
└── nuget.config
└── tools
├── CheckAssemblyVersion.ps1
├── CreateDebugNuget.ps1
├── CreateNuget.ps1
└── wget.exe
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # These owners will be the default owners for everything in
2 | # the repo. Unless a later match takes precedence,
3 | # @ReactiveDomain/ReactiveDomain-codeowners will be requested for
4 | # review when someone opens a pull request.
5 | * @ReactiveDomain/ReactiveDomain-codeowners
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Environment (please complete the following information):**
27 | - .NET version: [e.g. .NET 6]
28 | - ReactiveDomain version: [e.g. 0.8.22]
29 |
30 | **Additional context**
31 | Add any other context about the problem here.
32 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Questions
4 | url: https://github.com/ReactiveDomain/reactive-domain/discussions
5 | about: 'For general questions about ReactiveDomain, ask in the GitHub discussions'
6 | - name: Chat
7 | url: https://reactivedomain.slack.com
8 | about: 'Join the discussion on Slack'
9 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | **What does this pull request do?**
2 |
3 |
4 |
5 | **How does this pull request accomplish that goal?**
6 |
7 |
8 |
9 | **Why is this pull request important?**
10 |
11 |
12 |
13 | **Link to any issues that this resolves**
14 |
21 |
22 |
23 | **Checklist**
24 | - [ ] All unit tests in the solution must pass on all versions of .NET that the solution supports
25 | - [ ] Any new code must be covered by at least one unit test
26 | - [ ] All public methods must be documented with XML comments
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: required
2 | language: csharp
3 | os: windows
4 | mono: none
5 | dist: trusty
6 |
7 | branches:
8 | only:
9 | - master
10 | - /.*/
11 |
12 | addons:
13 | apt:
14 | packages:
15 | - powershell
16 |
17 | before_script:
18 | - powershell -executionpolicy unrestricted -File ./tools/CheckAssemblyVersion.ps1
19 |
20 | script:
21 | - choco install dotnet-5.0-sdk
22 | - echo $TRAVIS_BRANCH
23 | - echo $TRAVIS_BUILD_DIR
24 | - echo $TRAVIS_PULL_REQUEST
25 | - echo $TRAVIS_PULL_REQUEST_BRANCH
26 | - echo $TRAVIS_EVENT_TYPE
27 | - echo $STABLE
28 | - dotnet restore ./src/ReactiveDomain.sln -s https://api.nuget.org/v3/index.json
29 | - dotnet msbuild ./src/ReactiveDomain.sln -p:Configuration=Debug
30 | - dotnet msbuild ./src/ReactiveDomain.sln -p:Configuration=Release
31 | # - dotnet test ./src/ReactiveDomain.Messaging.Tests/ReactiveDomain.Messaging.Tests.csproj #TODO: Fix unit test
32 | - dotnet test ./src/ReactiveDomain.Foundation.Tests/ReactiveDomain.Foundation.Tests.csproj
33 | - dotnet test ./src/ReactiveDomain.Transport.Tests/ReactiveDomain.Transport.Tests.csproj
34 |
35 | after_success:
36 | - powershell -executionpolicy unrestricted -File ./tools/CreateNuget.ps1
37 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to ReactiveDomain
2 |
3 | Contributions can take many forms: open an issue, contribute code, enhance the documentation. We welcome contribtutions of any sort to ReactiveDomain. Here are some things to keep in mind when contributing:
4 |
5 | - [Code of Conduct](https://github.com/ReactiveDomain/reactive-domain/CODE_OF_CONDUCT.md)
6 | - [Issues](#issues)
7 | - [Feature Requests](#requests)
8 | - [Coding](#coding)
9 |
10 | ## Issues and Bugs
11 | Found a bug in the code or documentation? Submit an issue. Even better, submit a Pull Request to fix it!
12 |
13 | ## Feature Requests
14 | We welcome well-considered feature requests. For **major features**, please engage with us in [Slack](https://reactivedomain.slack.com) first to discuss it and work out the details. For **minor features**, feel free to submit a Pull Request right away.
15 |
16 | ## Coding
17 | ### Development Environment
18 | - Visual Studio 2022 (with latest patches/updates)
19 | - All versions of .NET currently supported in the solution: .NET Framework 4.8 & .NET 5.0.
20 |
21 | ### Coding Guidelines
22 | When submitting a Pull Request, keep these rules in mind:
23 | - All unit tests in the solution must pass on all versions of .NET that the solution supports
24 | - Any new code must be covered by at least one unit test
25 | - All public methods must be documented with XML comments
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Cloud-Connect
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://ci.appveyor.com/project/jageall/reactive-domain)
2 | [](https://travis-ci.org/linedata/reactive-domain)
3 | [](code_of_conduct.md)
4 |
5 | # Reactive Domain
6 |
7 | ## Overview
8 |
9 | Reactive Domain is an open source framework for implementing event sourcing in .NET projects using reactive programming principles. This includes interfaces for using [EventStoreDB](https://eventstore.com). It also provides a messaging framework and other tools for using CQRS.
10 |
11 | The framework is highly opinionated. It focuses on using a small number of consistent patterns and design principles in its public interfaces to enable developers to get up to speed quickly. Ease of use and "design for code review" have been the driving forces behind the framework's evolution. Where trade-offs have been necessary, these principles have been emphasized over performance.
12 |
13 | ## Contributing
14 |
15 | Pull requests are welcome! Take a look at the open issues, join our [discussion on Slack](https://reactivedomain.slack.com), or contribute in an area where you see a need. Contributors and participants on our Slack channels are expected to abide by the project's [code of conduct](CODE_OF_CONDUCT.md). Read the full guidelines on [contributing](CONTRIBUTING.md).
--------------------------------------------------------------------------------
/SUPPORT.md:
--------------------------------------------------------------------------------
1 | # Support
2 |
3 | For help getting started with ReactiveDomain or to discuss issues you encounter, join the [discussion on Slack](https://reactivedomain.slack.com).
--------------------------------------------------------------------------------
/Samples/Metadata/PersistedMetadata/Messages.cs:
--------------------------------------------------------------------------------
1 | using ReactiveDomain.Messaging;
2 |
3 | namespace Metadata_Sample_App
4 | {
5 | public class Messages
6 | {
7 | public class Greeting : Message
8 | {
9 | public readonly string Text;
10 | public Greeting(string text)
11 | {
12 | Text = text;
13 | }
14 | }
15 | public class Farewell : Message
16 | {
17 | public readonly string Text;
18 | public Farewell(string text)
19 | {
20 | Text = text;
21 | }
22 | }
23 | public class Sender
24 | {
25 | public string Name;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Samples/Metadata/PersistedMetadata/PersistedMetadata.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 | Metadata_Sample_App
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Samples/Metadata/PersistedMetadata/Program.cs:
--------------------------------------------------------------------------------
1 | using ReactiveDomain.Messaging.Bus;
2 | using Terminal.Gui;
3 |
4 | namespace Sample1
5 | {
6 | internal class Program
7 | {
8 | static void Main(string[] args)
9 | {
10 | Application.Init();
11 | Application.Top.Add(new Sample1.MessageWindow(new InMemoryBus("message bus")));
12 | Application.Run();
13 |
14 | Application.Shutdown();
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/Samples/Metadata/SimpleMetadata/Messages.cs:
--------------------------------------------------------------------------------
1 | using ReactiveDomain.Messaging;
2 |
3 | namespace Metadata_Sample_App
4 | {
5 | public class Messages
6 | {
7 | public class Greeting : Message
8 | {
9 | public readonly string Text;
10 | public Greeting(string text)
11 | {
12 | Text = text;
13 | }
14 | }
15 | public class Farewell : Message
16 | {
17 | public readonly string Text;
18 | public Farewell(string text)
19 | {
20 | Text = text;
21 | }
22 | }
23 | public class Sender
24 | {
25 | public string Name;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Samples/Metadata/SimpleMetadata/Program.cs:
--------------------------------------------------------------------------------
1 | using ReactiveDomain.Messaging.Bus;
2 | using Terminal.Gui;
3 |
4 | namespace Metadata_Sample_App
5 | {
6 | internal class Program
7 | {
8 | static void Main(string[] args)
9 | {
10 | Application.Init();
11 | Application.Top.Add(new Metadata_Sample_App.MessageWindow(new InMemoryBus("message bus")));
12 | Application.Run();
13 |
14 | Application.Shutdown();
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/Samples/Metadata/SimpleMetadata/SimpleMetadata.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 | Metadata_Sample_App
7 | enable
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/build/ReactiveDomain.Policy.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 |
7 | false
8 |
9 |
10 |
--------------------------------------------------------------------------------
/build/ReactiveDomain.Testing.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 |
7 | false
8 |
9 |
10 |
--------------------------------------------------------------------------------
/build/ReactiveDomain.UI.Testing.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 |
7 | false
8 |
9 |
10 |
--------------------------------------------------------------------------------
/build/ReactiveDomain.UI.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 |
7 | false
8 |
9 |
10 |
--------------------------------------------------------------------------------
/build/ReactiveDomain.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 |
7 | false
8 |
9 |
10 |
--------------------------------------------------------------------------------
/package.bat:
--------------------------------------------------------------------------------
1 | del .\nupkgs\*.* /q
2 | del .\bld\Debug\*.* /q
3 | del .\bld\pub\*.* /q
4 | dotnet restore .\src\ReactiveDomain.sln
5 | dotnet build .\src\ReactiveDomain.sln -c Debug
6 | dotnet publish .\src\ReactiveDomain.PolicyTool\ReactiveDomain.PolicyTool.csproj -p:PublishProfile=FolderProfile
7 | pwsh.exe -Command "& {.\tools\CreateDebugNuget.ps1 -local002}"
8 |
9 |
--------------------------------------------------------------------------------
/publish.bat:
--------------------------------------------------------------------------------
1 | del .\*.nukpg /q
2 | del .\bld\Release\*.* /q
3 | del .\bld\pub\*.* /q
4 | dotnet restore .\src\ReactiveDomain.sln
5 | dotnet build .\src\ReactiveDomain.sln -c Release
6 | dotnet publish .\src\ReactiveDomain.PolicyTool\ReactiveDomain.PolicyTool.csproj -c Release -p:PublishProfile=FolderProfile
7 | pwsh.exe -Command "& {.\tools\CreateNuget.ps1}"
8 |
9 |
--------------------------------------------------------------------------------
/src/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.cs]
2 |
3 | # xUnit1031: Do not use blocking task operations in test method
4 | dotnet_diagnostic.xUnit1031.severity = suggestion
5 |
6 | # VSSpell001: Spell Check
7 | dotnet_diagnostic.VSSpell001.severity = suggestion
8 |
--------------------------------------------------------------------------------
/src/.nuget/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ReactiveDomain/reactive-domain/05e5268f0ceef1034885905402590486fcb6fcad/src/.nuget/NuGet.exe
--------------------------------------------------------------------------------
/src/Dependency.Versions.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2.4.1
4 | 1.0.1
5 | 12.0.2
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/PolicyTool.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.2.32210.308
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveDomain.PolicyTool", "ReactiveDomain.PolicyTool\ReactiveDomain.PolicyTool.csproj", "{EE09B354-435A-4ECA-88E4-21718C3795EE}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {EE09B354-435A-4ECA-88E4-21718C3795EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {EE09B354-435A-4ECA-88E4-21718C3795EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {EE09B354-435A-4ECA-88E4-21718C3795EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {EE09B354-435A-4ECA-88E4-21718C3795EE}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {7D908F06-2C09-4FB2-A4A5-438AFDF4B433}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Audit/AuditRecord.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace ReactiveDomain.Audit
3 | {
4 | public class AuditRecord
5 | {
6 | public int Version = 0;
7 | public Guid PolicyUserId { get; set; }
8 | public Guid CommitId { get; set; }
9 | public string AggregateName { get; set; }
10 | public string EventName { get; set; }
11 | public DateTime EventDateUTC { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/IMetadata.cs:
--------------------------------------------------------------------------------
1 | namespace ReactiveDomain
2 | {
3 | ///
4 | /// Exposes methods for reading and writing message metadata.
5 | ///
6 | public interface IMetadata
7 | {
8 | ///
9 | /// Gets the metadata object of a type.
10 | ///
11 | /// The type of metadata to retrieve.
12 | /// An object of that type.
13 | T Read();
14 | ///
15 | /// Tries to get a metadata object of a type.
16 | ///
17 | /// The type of metadata to retrieve.
18 | /// The metadata object that was read.
19 | /// True if a metadata object of the type was found, otherwise false.
20 | bool TryRead(out T value);
21 | ///
22 | /// Adds or replaces a metadata object of a type.
23 | ///
24 | /// The type of metadata to write.
25 | /// The metadata object to write.
26 | void Write(T metadatum);
27 | }
28 | }
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/IMetadataSource.cs:
--------------------------------------------------------------------------------
1 | namespace ReactiveDomain
2 | {
3 | ///
4 | /// An interface for types that have .
5 | ///
6 | public interface IMetadataSource
7 | {
8 | ///
9 | /// Gets the object's metadata.
10 | ///
11 | /// The object's .
12 | Metadata ReadMetadata();
13 | ///
14 | /// Initializes an object's metadata using default values.
15 | ///
16 | /// The initialized .
17 | Metadata Initialize();
18 | ///
19 | /// Initializes an object using the provided .
20 | ///
21 | /// The to use for initialization.
22 | void Initialize(Metadata md);
23 | }
24 | }
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Logging/ILogger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ReactiveDomain.Logging
4 | {
5 | public enum LogLevel
6 | {
7 | Fatal = 0,
8 | Error = 1,
9 | Info = 2,
10 | Debug = 3,
11 | Trace = 4
12 | }
13 |
14 | public interface ILogger
15 | {
16 | void Flush(TimeSpan? maxTimeToWait = null);
17 |
18 | LogLevel LogLevel { get; }
19 |
20 | void Fatal(string text);
21 | void Error(string text);
22 | void Info(string text);
23 | void Debug(string text);
24 | void Trace(string text);
25 |
26 | void Fatal(string format, params object[] args);
27 | void Error(string format, params object[] args);
28 | void Info(string format, params object[] args);
29 | void Debug(string format, params object[] args);
30 | void Trace(string format, params object[] args);
31 |
32 | void FatalException(Exception exc, string text);
33 | void ErrorException(Exception exc, string text);
34 | void InfoException(Exception exc, string text);
35 | void DebugException(Exception exc, string text);
36 | void TraceException(Exception exc, string text);
37 |
38 | void FatalException(Exception exc, string format, params object[] args);
39 | void ErrorException(Exception exc, string format, params object[] args);
40 | void InfoException(Exception exc, string format, params object[] args);
41 | void DebugException(Exception exc, string format, params object[] args);
42 | void TraceException(Exception exc, string format, params object[] args);
43 | }
44 | }
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Logging/NullLogger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ReactiveDomain.Logging
4 | {
5 | public class NullLogger : ILogger
6 | {
7 | public void Flush(TimeSpan? maxTimeToWait = null) { }
8 | public LogLevel LogLevel => LogLevel.Fatal;
9 | public void Fatal(string text) { }
10 | public void Error(string text) { }
11 | public void Info(string text) { }
12 | public void Debug(string text) { }
13 | public void Trace(string text) { }
14 | public void Fatal(string format, params object[] args) { }
15 | public void Error(string format, params object[] args) { }
16 | public void Info(string format, params object[] args) { }
17 | public void Debug(string format, params object[] args) { }
18 | public void Trace(string format, params object[] args) { }
19 | public void FatalException(Exception exc, string text) { }
20 | public void ErrorException(Exception exc, string text) { }
21 | public void InfoException(Exception exc, string text) { }
22 | public void DebugException(Exception exc, string text) { }
23 | public void TraceException(Exception exc, string text) { }
24 | public void FatalException(Exception exc, string format, params object[] args) { }
25 | public void ErrorException(Exception exc, string format, params object[] args) { }
26 | public void InfoException(Exception exc, string format, params object[] args) { }
27 | public void DebugException(Exception exc, string format, params object[] args) { }
28 | public void TraceException(Exception exc, string format, params object[] args) { }
29 |
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/MetadatumNotFoundException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ReactiveDomain
4 | {
5 | ///
6 | /// Indicates that a requested metadata type was not found.
7 | ///
8 | public class MetadatumNotFoundException : Exception { }
9 | }
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/ReactiveDomain.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $(LibTargetFrameworks)
6 | ReactiveDomain
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Util/CustomConfigLoader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Configuration;
3 | using System.Linq;
4 | using System.Xml;
5 | using System.Xml.Serialization;
6 |
7 | namespace ReactiveDomain.Util
8 | {
9 | public class CustomConfigLoader : IConfigurationSectionHandler
10 | {
11 | public object Create(object parent, object configContext, XmlNode section)
12 | {
13 | if (section == null)
14 | {
15 | throw new ArgumentNullException($"XMLNode passed in is null.");
16 | }
17 |
18 | var type = AppDomain.CurrentDomain.GetAssemblies()
19 | .SelectMany(a => a.GetTypes())
20 | .FirstOrDefault(t => t.Name == section.Name);
21 |
22 | if (type == null)
23 | {
24 | throw new ArgumentException($"Type with name {section.Name} couldn't be found.");
25 | }
26 |
27 | XmlSerializer ser = new XmlSerializer(type, new XmlRootAttribute(section.Name));
28 |
29 | using (XmlReader reader = new XmlNodeReader(section))
30 | {
31 | return ser.Deserialize(reader);
32 | }
33 | }
34 |
35 | }
36 | }
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Util/Disposer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace ReactiveDomain.Util
3 | {
4 | public class Disposer:IDisposable
5 | {
6 | private Func _disposeFunc;
7 |
8 | public Disposer(Func disposeFunc)
9 | {
10 | _disposeFunc = disposeFunc ?? throw new ArgumentNullException(nameof(disposeFunc));
11 | }
12 |
13 | private bool _disposed;
14 | public void Dispose()
15 | {
16 | if (_disposed) return;
17 | try{
18 | _disposeFunc();
19 | _disposeFunc = null;
20 | }
21 | catch {
22 | //ignore
23 | }
24 | _disposed = true;
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Util/Empty.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ReactiveDomain.Util
4 | {
5 | public static class Empty
6 | {
7 | public static readonly byte[] ByteArray = new byte[0];
8 | public static readonly string[] StringArray = new string[0];
9 | public static readonly object[] ObjectArray = new object[0];
10 |
11 | public static readonly Action Action = () => { };
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Util/EnumerableExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 |
6 | namespace ReactiveDomain.Util
7 | {
8 | public static class EnumerableExtensions
9 | {
10 | public static IEnumerable Safe(this IEnumerable collection)
11 | {
12 | return collection ?? Enumerable.Empty();
13 | }
14 |
15 | public static bool Contains(this IEnumerable collection, Predicate condition)
16 | {
17 | return collection.Any(x => condition(x));
18 | }
19 |
20 | public static bool IsEmpty(this IEnumerable collection)
21 | {
22 | if (collection == null)
23 | return true;
24 | var coll = collection as ICollection;
25 | if (coll != null)
26 | return coll.Count == 0;
27 | return !collection.Any();
28 | }
29 |
30 | public static bool IsNotEmpty(this IEnumerable collection)
31 | {
32 | return !IsEmpty(collection);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Util/FileUtils.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace ReactiveDomain.Util
4 | {
5 | public static class FileUtils
6 | {
7 | public static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
8 | {
9 | // Get the subdirectories for the specified directory.
10 | var dir = new DirectoryInfo(sourceDirName);
11 |
12 | if (!dir.Exists)
13 | throw new DirectoryNotFoundException("Source directory does not exist or could not be found: " + sourceDirName);
14 |
15 | var subdirs = copySubDirs ? dir.GetDirectories() : null;
16 |
17 | // If the destination directory doesn't exist, create it.
18 | if (!Directory.Exists(destDirName))
19 | Directory.CreateDirectory(destDirName);
20 |
21 | // Get the files in the directory and copy them to the new location.
22 | foreach (FileInfo file in dir.GetFiles())
23 | {
24 | file.CopyTo(Path.Combine(destDirName, file.Name), false);
25 | }
26 |
27 | if (copySubDirs)
28 | {
29 | foreach (DirectoryInfo subdir in subdirs)
30 | {
31 | DirectoryCopy(subdir.FullName, Path.Combine(destDirName, subdir.Name), true);
32 | }
33 | }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Util/FluentExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ReactiveDomain.Util
4 | {
5 | public static class FluentExtensions {
6 |
7 | public static T If(this T t, Func cond, Func builder) where T : class {
8 | return cond() ? builder(t) : t;
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Util/HostName.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 |
4 | namespace ReactiveDomain.Util
5 | {
6 | public class HostName
7 | {
8 | public static string Combine(Uri requestedUrl, string relativeUri, params object[] arg)
9 | {
10 | try
11 | {
12 | return CombineHostNameAndPath(requestedUrl, relativeUri, arg);
13 | }
14 | catch (Exception e)
15 | {
16 | Debug.WriteLine("Failed to combine hostname with relative path: {0}", e.Message);
17 | return relativeUri;
18 | }
19 | }
20 |
21 | private static string CombineHostNameAndPath(Uri requestedUrl,
22 | string relativeUri,
23 | object[] arg)
24 | {
25 | //TODO: encode???
26 | var path = string.Format(relativeUri, arg);
27 | return new UriBuilder(requestedUrl.Scheme, requestedUrl.Host, requestedUrl.Port, path).Uri.AbsoluteUri;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Util/IPEndPointComparer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Net;
3 |
4 | namespace ReactiveDomain.Util
5 | {
6 | public class IPEndPointComparer : IComparer
7 | {
8 | public int Compare(IPEndPoint x, IPEndPoint y)
9 | {
10 | var xx = x.Address.ToString();
11 | var yy = y.Address.ToString();
12 | var result = string.CompareOrdinal(xx, yy);
13 | return result == 0 ? x.Port.CompareTo(y.Port) : result;
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Util/IpEndPointExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Net;
2 |
3 | namespace ReactiveDomain.Util
4 | {
5 | public static class IpEndPointExtensions
6 | {
7 | public static string ToHttpUrl(this IPEndPoint endPoint, string rawUrl = null)
8 | {
9 | return string.Format("http://{0}:{1}/{2}",
10 | endPoint.Address,
11 | endPoint.Port,
12 | rawUrl != null ? rawUrl.TrimStart('/') : string.Empty);
13 | }
14 |
15 | public static string ToHttpUrl(this IPEndPoint endPoint, string formatString, params object[] args)
16 | {
17 | return string.Format("http://{0}:{1}/{2}",
18 | endPoint.Address,
19 | endPoint.Port,
20 | string.Format(formatString.TrimStart('/'), args));
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Util/MD5Hash.cs:
--------------------------------------------------------------------------------
1 | // ReSharper disable MemberCanBePrivate.Global
2 | // ReSharper disable UnusedMember.Global
3 |
4 | using System;
5 | using System.IO;
6 | using System.Security.Cryptography;
7 |
8 | namespace ReactiveDomain.Util
9 | {
10 | public class MD5Hash
11 | {
12 | public static byte[] GetHashFor(Stream s)
13 | {
14 | //when using this, it will calculate from this point to the END of the stream!
15 | using (MD5 md5 = MD5.Create())
16 | return md5.ComputeHash(s);
17 | }
18 |
19 | public static byte[] GetHashFor(Stream s, int startPosition, long count)
20 | {
21 | Ensure.Nonnegative(count, "count");
22 |
23 | using (MD5 md5 = MD5.Create())
24 | {
25 | ContinuousHashFor(md5, s, startPosition, count);
26 | md5.TransformFinalBlock(Empty.ByteArray, 0, 0);
27 | return md5.Hash;
28 | }
29 | }
30 |
31 | public static void ContinuousHashFor(MD5 md5, Stream s, int startPosition, long count)
32 | {
33 | Ensure.NotNull(md5, "md5");
34 | Ensure.Nonnegative(count, "count");
35 |
36 | // ReSharper disable once RedundantCheckBeforeAssignment
37 | if (s.Position != startPosition)
38 | s.Position = startPosition;
39 |
40 | var buffer = new byte[4096];
41 | long toRead = count;
42 | while (toRead > 0)
43 | {
44 | int read = s.Read(buffer, 0, (int)Math.Min(toRead, buffer.Length));
45 | if (read == 0)
46 | break;
47 |
48 | md5.TransformBlock(buffer, 0, read, null, 0);
49 | toRead -= read;
50 | }
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Util/ShellExecutor.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace ReactiveDomain.Util
4 | {
5 | public static class ShellExecutor
6 | {
7 | public static string GetOutput(string command, string args = null)
8 | {
9 | var info = new ProcessStartInfo
10 | {
11 | RedirectStandardOutput = true,
12 | UseShellExecute = false,
13 | CreateNoWindow = true,
14 | FileName = command,
15 | Arguments = args ?? string.Empty
16 | };
17 |
18 | using (var process = Process.Start(info))
19 | {
20 | // ReSharper disable once PossibleNullReferenceException
21 | var res = process.StandardOutput.ReadToEnd();
22 | return res;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Core/Util/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace ReactiveDomain.Util
2 | {
3 | public static class StringExtensions
4 | {
5 | public static bool IsEmptyString(this string s)
6 | {
7 | return string.IsNullOrEmpty(s);
8 | }
9 |
10 | public static bool IsNotEmptyString(this string s)
11 | {
12 | return !string.IsNullOrEmpty(s);
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Foundation.Tests/Domain/CapturingRoute.cs:
--------------------------------------------------------------------------------
1 | namespace ReactiveDomain.Foundation.Tests.Domain
2 | {
3 | public class CapturingRoute
4 | {
5 | public CapturingRoute()
6 | {
7 | Captured = null;
8 | }
9 |
10 | public void Capture(TEvent result)
11 | {
12 | Captured = result;
13 | }
14 |
15 | public object Captured { get; private set; }
16 | }
17 | }
--------------------------------------------------------------------------------
/src/ReactiveDomain.Foundation.Tests/Domain/MetadatumTests.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Albedo;
3 | using AutoFixture;
4 | using AutoFixture.Idioms;
5 | using Xunit;
6 |
7 | namespace ReactiveDomain.Domain.Tests
8 | {
9 | public class MetadatumTests
10 | {
11 | private readonly Fixture _fixture;
12 |
13 | public MetadatumTests()
14 | {
15 | _fixture = new Fixture();
16 | }
17 |
18 | [Fact]
19 | public void BothNameAndValueCanNotBeNull()
20 | {
21 | new GuardClauseAssertion(_fixture).
22 | Verify(Constructors.Select(() => new Metadatum(null, null)));
23 | }
24 |
25 | [Fact]
26 | public void BothNameAndValueReturnExpectedResult()
27 | {
28 | new ConstructorInitializedMemberAssertion(_fixture).
29 | Verify(Constructors.Select(() => new Metadatum("name", "value")));
30 | }
31 |
32 | [Fact]
33 | public void ToKeyValuePairReturnsExpectedResult()
34 | {
35 | var sut = new Metadatum("name", "value");
36 | var result = sut.ToKeyValuePair();
37 | Assert.Equal(new KeyValuePair("name", "value"), result);
38 | }
39 |
40 | [Fact]
41 | public void VerifyEquality()
42 | {
43 | new CompositeIdiomaticAssertion(
44 | new EqualsNewObjectAssertion(_fixture),
45 | new EqualsNullAssertion(_fixture),
46 | new EqualsSelfAssertion(_fixture),
47 | new GetHashCodeSuccessiveAssertion(_fixture),
48 | new EqualsSuccessiveAssertion(_fixture))
49 | .Verify(typeof(Metadatum));
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Foundation.Tests/EmbeddedStreamStoreConnectionCollection.cs:
--------------------------------------------------------------------------------
1 | using ReactiveDomain.Testing;
2 | using Xunit;
3 |
4 | namespace ReactiveDomain.Foundation.Tests
5 | {
6 | //n.b a copy of this marker class must be in the assembly with the test classes
7 | //copy and place in the local namespace to avoid collisions
8 | [CollectionDefinition(nameof(EmbeddedStreamStoreConnectionCollection))]
9 | public class EmbeddedStreamStoreConnectionCollection : ICollectionFixture
10 | {
11 | }
12 | }
--------------------------------------------------------------------------------
/src/ReactiveDomain.Foundation.Tests/Logging/with_message_logging_enabled.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using ReactiveDomain.Foundation.EventStore;
4 | using ReactiveDomain.Messaging.Bus;
5 |
6 | namespace ReactiveDomain.Foundation.Tests.Logging
7 | {
8 | // ReSharper disable once InconsistentNaming
9 | public abstract class with_message_logging_enabled :IDisposable
10 | {
11 | protected readonly IStreamStoreConnection Connection;
12 | protected IDispatcher Bus;
13 | protected EventStoreMessageLogger Logging;
14 | protected string StreamName = $"LogTest-{Guid.NewGuid():N}";
15 | protected StreamStoreRepository Repo;
16 | protected PrefixedCamelCaseStreamNameBuilder StreamNameBuilder;
17 | protected IEventSerializer EventSerializer;
18 |
19 | protected with_message_logging_enabled(IStreamStoreConnection connection)
20 | {
21 | Connection = connection;
22 | Bus = new Dispatcher(nameof(with_message_logging_enabled));
23 | StreamNameBuilder = new PrefixedCamelCaseStreamNameBuilder("UnitTest");
24 | EventSerializer = new JsonMessageSerializer();
25 | Repo = new StreamStoreRepository(StreamNameBuilder, Connection, new JsonMessageSerializer());
26 | // instantiate Logger class that inherits from QueuedSubscriber
27 | Logging = new EventStoreMessageLogger(Bus,
28 | Connection,
29 | StreamName,
30 | true);
31 | }
32 |
33 |
34 | public void Dispose() {
35 | Dispose(true);
36 | GC.SuppressFinalize(this);
37 | }
38 |
39 | protected virtual void Dispose(bool disposing) {
40 | if (!disposing) return;
41 |
42 | Bus?.Dispose();
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Foundation.Tests/StreamListenerTests/Common/CommonHelpers.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using ReactiveDomain.Messaging;
3 | using ReactiveDomain.Testing;
4 |
5 | namespace ReactiveDomain.Foundation.Tests.StreamListenerTests.Common
6 | {
7 | internal static class CommonHelpers
8 | {
9 | internal static void WaitForStream(IStreamStoreConnection conn, string streamName)
10 | {
11 | //wait for the category projection to be written
12 | AssertEx.IsOrBecomesTrue(
13 | () =>
14 | {
15 | try
16 | {
17 | return conn.ReadStreamForward(streamName, 0, 1) != null;
18 | }
19 | catch
20 | {
21 | return false;
22 | }
23 | },
24 | 2000,
25 | $"Stream '{streamName}' not created");
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Foundation.Tests/StreamListenerTests/Common/TestStreamNameBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ReactiveDomain.Foundation.Tests.StreamListenerTests.Common
4 | {
5 | ///
6 | /// Generate stream names for testing.
7 | ///
8 | ///
9 | /// todo:
10 | /// The use of the extra Guid doesn't match the generation by the
11 | /// and the checks for existing category and event streams fail.
12 | /// tests the stream name generation. So switching to the PrefixedCamelCaseStreamNameBuilder. Leaving these here so Chris can
13 | /// agree and remove or correct me.
14 | /// end todo
15 | ///
16 | internal class TestStreamNameBuilder : IStreamNameBuilder
17 | {
18 | private readonly Guid _testRunGuid;
19 |
20 | public TestStreamNameBuilder(Guid testRunGuid)
21 | {
22 | _testRunGuid = testRunGuid;
23 | }
24 | public string GenerateForAggregate(Type type, Guid id)
25 | {
26 | return $"{type.Name}-{id:N}{_testRunGuid:N}";
27 | }
28 |
29 | public string GenerateForCategory(Type type)
30 | {
31 | //mock category stream, can't use $ here
32 | return $"ce-{type.Name}{_testRunGuid:N}";
33 | }
34 |
35 | public string GenerateForEventType(string type)
36 | {
37 | //mock event type stream, can't use $ here
38 | return $"et-{type}{_testRunGuid:N}";
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Foundation.Tests/can_serialize_correlated_messages.cs:
--------------------------------------------------------------------------------
1 | using ReactiveDomain.Messaging;
2 | using ReactiveDomain.Testing;
3 | using System;
4 | using Xunit;
5 |
6 | namespace ReactiveDomain.Foundation.Tests {
7 |
8 | // ReSharper disable once InconsistentNaming
9 | public class when_serializing_correlated_messages {
10 | [Fact]
11 | public void can_use_json_message_serializer() {
12 |
13 | var evt = new TestEvent();
14 | var evt2 = MessageBuilder
15 | .From(evt)
16 | .Build(()=> new TestEvent());
17 |
18 | var serializer = new JsonMessageSerializer();
19 |
20 | var data = serializer.Serialize(evt);
21 | var data2 = serializer.Serialize(evt2);
22 |
23 | var dEvent = (TestEvent)serializer.Deserialize(data);
24 | var dEvent2 = (TestEvent)serializer.Deserialize(data2);
25 |
26 | Assert.Equal(evt.MsgId,dEvent.MsgId);
27 | Assert.Equal(evt.CausationId,dEvent.CausationId);
28 | Assert.Equal(evt.CorrelationId,dEvent.CorrelationId);
29 |
30 | Assert.Equal(evt2.MsgId,dEvent2.MsgId);
31 | Assert.Equal(evt2.CausationId,dEvent2.CausationId);
32 | Assert.Equal(evt2.CorrelationId, dEvent2.CorrelationId);
33 | }
34 | public class TestEvent : ICorrelatedMessage {
35 | public Guid MsgId { get; private set; }
36 | public TestEvent()
37 | {
38 | MsgId = Guid.NewGuid();
39 | }
40 | public Guid CorrelationId { get; set; }
41 | public Guid CausationId { get; set; }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Foundation/BootStrap.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using ReactiveDomain.Logging;
3 |
4 | namespace ReactiveDomain.Foundation
5 | {
6 | public static class BootStrap
7 | {
8 | private static readonly ILogger Log = LogManager.GetLogger("ReactiveDomain");
9 | private static readonly string AssemblyName;
10 | static BootStrap()
11 | {
12 | var fullName = Assembly.GetExecutingAssembly().FullName;
13 | Log.Info(fullName + " Loaded.");
14 | AssemblyName = fullName.Split(new[] { ',' })[0];
15 |
16 | }
17 | public static void Load()
18 | {
19 | Log.Info(AssemblyName + " Loaded.");
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/ReactiveDomain.Foundation/Domain/ChildEntity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ReactiveDomain.Foundation.Domain
4 | {
5 | public abstract class ChildEntity
6 | {
7 | public readonly Guid Id;
8 |
9 | private readonly Action