Skip to content

Commit

Permalink
#371 Introduce working example service.
Browse files Browse the repository at this point in the history
  • Loading branch information
adamjstone committed Aug 23, 2020
1 parent 60a9539 commit 9b305c7
Show file tree
Hide file tree
Showing 64 changed files with 669 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ public ApplicationDependencyPackage()
protected override IEnumerable<IDependencyModule<ServiceCollection>> CreateModules(IConfiguration applicationConfiguration) => new IDependencyModule<ServiceCollection>[]
{
new DatabaseContextDependencyModule(applicationConfiguration),
new ServiceBusDependencyModule(applicationConfiguration)
new ServiceBusDependencyModule(applicationConfiguration),
new CommandHandlerModule(applicationConfiguration),
new EventHandlerModule(applicationConfiguration),
new MessageHandlerModule(applicationConfiguration)
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// =================================================================================================================================

using Microsoft.Extensions.Configuration;
using RapidField.SolidInstruments.Command;
using RapidField.SolidInstruments.Core;
using RapidField.SolidInstruments.InversionOfControl;
using RapidField.SolidInstruments.Messaging.DotNetNative.Service;
Expand Down Expand Up @@ -52,9 +53,20 @@ protected override void AddListeners(IMessageListeningProfile listeningProfile,
{
try
{
// Add standard listeners.
listeningProfile.AddExceptionRaisedEventListener();
listeningProfile.AddHeartbeatListener();
listeningProfile.AddPingRequestListener();

// Add command listeners.
listeningProfile.AddCommandListener<Commands.ModelState.User.CreateDomainModelCommand, Messages.Command.ModelState.User.CreateDomainModelCommandMessage>();
listeningProfile.AddCommandListener<Commands.ModelState.User.DeleteDomainModelCommand, Messages.Command.ModelState.User.DeleteDomainModelCommandMessage>();
listeningProfile.AddCommandListener<Commands.ModelState.User.UpdateDomainModelCommand, Messages.Command.ModelState.User.UpdateDomainModelCommandMessage>();

// Add event listeners.
listeningProfile.AddEventListener<Events.ModelState.User.DomainModelCreatedEvent, Messages.Event.ModelState.User.DomainModelCreatedEventMessage>();
listeningProfile.AddEventListener<Events.ModelState.User.DomainModelDeletedEvent, Messages.Event.ModelState.User.DomainModelDeletedEventMessage>();
listeningProfile.AddEventListener<Events.ModelState.User.DomainModelUpdatedEvent, Messages.Event.ModelState.User.DomainModelUpdatedEventMessage>();
}
finally
{
Expand Down Expand Up @@ -106,6 +118,9 @@ protected override void OnExecutionStarting(IDependencyScope dependencyScope, IC
{
var databaseContext = dependencyScope.Resolve<DatabaseContext>();
databaseContext.Database.EnsureCreated();
var mediator = dependencyScope.Resolve<ICommandMediator>();
mediator.Process(new Messages.Command.ModelState.User.CreateDomainModelCommandMessage(new Commands.ModelState.User.CreateDomainModelCommand(Models.User.DomainModel.Named.StevenCallahan)));
mediator.Process(new Messages.Command.ModelState.User.CreateDomainModelCommandMessage(new Commands.ModelState.User.CreateDomainModelCommand(Models.User.DomainModel.Named.TomSmith)));
}
finally
{
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// =================================================================================================================================
// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
// =================================================================================================================================

using Microsoft.Extensions.Configuration;
using RapidField.SolidInstruments.Command.DotNetNative;
using System;

namespace RapidField.SolidInstruments.Example.Domain.AccessControl
{
/// <summary>
/// Encapsulates container configuration for access control domain command handlers.
/// </summary>
public sealed class CommandHandlerModule : DotNetNativeCommandHandlerModule
{
/// <summary>
/// Initializes a new instance of the <see cref="CommandHandlerModule" /> class.
/// </summary>
/// <param name="applicationConfiguration">
/// Configuration information for the application.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="applicationConfiguration" /> is <see langword="null" />.
/// </exception>
public CommandHandlerModule(IConfiguration applicationConfiguration)
: base(applicationConfiguration)
{
return;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// =================================================================================================================================
// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
// =================================================================================================================================

using RapidField.SolidInstruments.Command;
using RapidField.SolidInstruments.DataAccess;
using System;
using DataAccessModel = RapidField.SolidInstruments.Example.Domain.Models.User.AggregateDataAccessModel;
using DomainModel = RapidField.SolidInstruments.Example.Domain.Models.User.DomainModel;
using DomainModelCommand = RapidField.SolidInstruments.Example.Domain.Commands.ModelState.User.CreateDomainModelCommand;

namespace RapidField.SolidInstruments.Example.Domain.AccessControl.CommandHandlers.ModelState.User
{
/// <summary>
/// Processes a single <see cref="DomainModelCommand" />.
/// </summary>
public sealed class CreateDomainModelCommandHandler : CreateDomainModelCommandHandler<Guid, DomainModel, DataAccessModel, DomainModelCommand>
{
/// <summary>
/// Initializes a new instance of the <see cref="CreateDomainModelCommandHandler" /> class.
/// </summary>
/// <param name="mediator">
/// A processing intermediary that is used to process sub-commands.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="mediator" /> is <see langword="null" />.
/// </exception>
public CreateDomainModelCommandHandler(ICommandMediator mediator)
: base(mediator)
{
return;
}

/// <summary>
/// Releases all resources consumed by the current <see cref="CreateDomainModelCommandHandler" />.
/// </summary>
/// <param name="disposing">
/// A value indicating whether or not managed resources should be released.
/// </param>
protected override void Dispose(Boolean disposing) => base.Dispose(disposing);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// =================================================================================================================================
// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
// =================================================================================================================================

using RapidField.SolidInstruments.Command;
using RapidField.SolidInstruments.DataAccess;
using System;
using DataAccessModel = RapidField.SolidInstruments.Example.Domain.Models.User.AggregateDataAccessModel;
using DomainModel = RapidField.SolidInstruments.Example.Domain.Models.User.DomainModel;
using DomainModelCommand = RapidField.SolidInstruments.Example.Domain.Commands.ModelState.User.DeleteDomainModelCommand;

namespace RapidField.SolidInstruments.Example.Domain.AccessControl.CommandHandlers.ModelState.User
{
/// <summary>
/// Processes a single <see cref="DomainModelCommand" />.
/// </summary>
public sealed class DeleteDomainModelCommandHandler : DeleteDomainModelCommandHandler<Guid, DomainModel, DataAccessModel, DomainModelCommand>
{
/// <summary>
/// Initializes a new instance of the <see cref="DeleteDomainModelCommandHandler" /> class.
/// </summary>
/// <param name="mediator">
/// A processing intermediary that is used to process sub-commands.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="mediator" /> is <see langword="null" />.
/// </exception>
public DeleteDomainModelCommandHandler(ICommandMediator mediator)
: base(mediator)
{
return;
}

/// <summary>
/// Releases all resources consumed by the current <see cref="DeleteDomainModelCommandHandler" />.
/// </summary>
/// <param name="disposing">
/// A value indicating whether or not managed resources should be released.
/// </param>
protected override void Dispose(Boolean disposing) => base.Dispose(disposing);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// =================================================================================================================================
// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
// =================================================================================================================================

using RapidField.SolidInstruments.Command;
using RapidField.SolidInstruments.DataAccess;
using System;
using DataAccessModel = RapidField.SolidInstruments.Example.Domain.Models.User.AggregateDataAccessModel;
using DomainModel = RapidField.SolidInstruments.Example.Domain.Models.User.DomainModel;
using DomainModelCommand = RapidField.SolidInstruments.Example.Domain.Commands.ModelState.User.UpdateDomainModelCommand;

namespace RapidField.SolidInstruments.Example.Domain.AccessControl.CommandHandlers.ModelState.User
{
/// <summary>
/// Processes a single <see cref="DomainModelCommand" />.
/// </summary>
public sealed class UpdateDomainModelCommandHandler : UpdateDomainModelCommandHandler<Guid, DomainModel, DataAccessModel, DomainModelCommand>
{
/// <summary>
/// Initializes a new instance of the <see cref="UpdateDomainModelCommandHandler" /> class.
/// </summary>
/// <param name="mediator">
/// A processing intermediary that is used to process sub-commands.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="mediator" /> is <see langword="null" />.
/// </exception>
public UpdateDomainModelCommandHandler(ICommandMediator mediator)
: base(mediator)
{
return;
}

/// <summary>
/// Releases all resources consumed by the current <see cref="UpdateDomainModelCommandHandler" />.
/// </summary>
/// <param name="disposing">
/// A value indicating whether or not managed resources should be released.
/// </param>
protected override void Dispose(Boolean disposing) => base.Dispose(disposing);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ protected override void OnModelCreating(IConfiguration applicationConfiguration,
{
try
{
_ = modelBuilder.Entity<UserModel>().ToTable(UserModel.TableName);
_ = modelBuilder.Entity<UserModel>();
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
// =================================================================================================================================

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using RapidField.SolidInstruments.DataAccess.DotNetNative.Ef;
using RapidField.SolidInstruments.DataAccess.DotNetNative.Extensions;
using RapidField.SolidInstruments.Example.Domain.AccessControl.Repositories;
using System;
using UserModel = RapidField.SolidInstruments.Example.Domain.Models.User.AggregateDataAccessModel;

namespace RapidField.SolidInstruments.Example.Domain.AccessControl
{
/// <summary>
/// Encapsulates native .NET container configuration for the AccessControl database connection and related data access
/// dependencies.
/// Encapsulates container configuration for the AccessControl database connection and related data access dependencies.
/// </summary>
public sealed class DatabaseContextDependencyModule : DotNetNativeEntityFrameworkDataStoreDependencyModule<DatabaseContext, DatabaseContextRepositoryFactory>
{
Expand All @@ -28,5 +31,16 @@ public DatabaseContextDependencyModule(IConfiguration applicationConfiguration)
{
return;
}

/// <summary>
/// Registers additional components.
/// </summary>
/// <param name="configurator">
/// An object that configures containers.
/// </param>
/// <param name="applicationConfiguration">
/// Configuration information for the application.
/// </param>
protected override void RegisterCustomComponents(ServiceCollection configurator, IConfiguration applicationConfiguration) => _ = configurator.AddStandardDataAccessModelCommandHandlers<Guid, UserModel, UserRepository>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// =================================================================================================================================
// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
// =================================================================================================================================

using Microsoft.Extensions.Configuration;
using RapidField.SolidInstruments.EventAuthoring.DotNetNative;
using System;

namespace RapidField.SolidInstruments.Example.Domain.AccessControl
{
/// <summary>
/// Encapsulates container configuration for access control domain event handlers.
/// </summary>
public sealed class EventHandlerModule : DotNetNativeEventHandlerModule
{
/// <summary>
/// Initializes a new instance of the <see cref="EventHandlerModule" /> class.
/// </summary>
/// <param name="applicationConfiguration">
/// Configuration information for the application.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="applicationConfiguration" /> is <see langword="null" />.
/// </exception>
public EventHandlerModule(IConfiguration applicationConfiguration)
: base(applicationConfiguration)
{
return;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// =================================================================================================================================
// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
// =================================================================================================================================

using RapidField.SolidInstruments.Command;
using RapidField.SolidInstruments.Core.Concurrency;
using RapidField.SolidInstruments.Core.Extensions;
using RapidField.SolidInstruments.EventAuthoring;
using System;
using System.Collections.Generic;
using DomainModel = RapidField.SolidInstruments.Example.Domain.Models.User.DomainModel;
using DomainModelEvent = RapidField.SolidInstruments.Example.Domain.Events.ModelState.User.DomainModelCreatedEvent;

namespace RapidField.SolidInstruments.Example.Domain.AccessControl.EventHandlers.ModelState.User
{
/// <summary>
/// Processes a single <see cref="DomainModelEvent" />.
/// </summary>
public sealed class DomainModelCreatedEventHandler : DomainModelCreatedEventHandler<DomainModel, DomainModelEvent>
{
/// <summary>
/// Initializes a new instance of the <see cref="DomainModelCreatedEventHandler" /> class.
/// </summary>
/// <param name="mediator">
/// A processing intermediary that is used to process sub-commands.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="mediator" /> is <see langword="null" />.
/// </exception>
public DomainModelCreatedEventHandler(ICommandMediator mediator)
: base(mediator)
{
return;
}

/// <summary>
/// Releases all resources consumed by the current <see cref="DomainModelCreatedEventHandler" />.
/// </summary>
/// <param name="disposing">
/// A value indicating whether or not managed resources should be released.
/// </param>
protected override void Dispose(Boolean disposing) => base.Dispose(disposing);

/// <summary>
/// Processes the specified domain model.
/// </summary>
/// <param name="model">
/// The model that was created.
/// </param>
/// <param name="labels">
/// A collection of textual labels that provide categorical and/or contextual information about the event.
/// </param>
/// <param name="correlationIdentifier">
/// A unique identifier to assign to sub-commands.
/// </param>
/// <param name="mediator">
/// A processing intermediary that is used to process sub-commands.
/// </param>
/// <param name="controlToken">
/// A token that represents and manages contextual thread safety.
/// </param>
protected override void Process(DomainModel model, IEnumerable<String> labels, Guid correlationIdentifier, ICommandMediator mediator, IConcurrencyControlToken controlToken) => Console.WriteLine($"A user was created (identifier: {model?.Identifier.ToSerializedString()}).");
}
}
Loading

0 comments on commit 9b305c7

Please sign in to comment.