Skip to content

Commit

Permalink
Added roslyn rule for registering aggregate prefixes. #10
Browse files Browse the repository at this point in the history
  • Loading branch information
jezzsantos committed Mar 23, 2024
1 parent 413fb8f commit f22dcaa
Show file tree
Hide file tree
Showing 48 changed files with 696 additions and 193 deletions.
22 changes: 11 additions & 11 deletions docs/design-principles/0050-domain-driven-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ An entity class should derive from `EntityBase,` and the designer should decide
For example,

```c#
public sealed class UnavailabilityEntity : EntityBase
public sealed class Unavailability : EntityBase
{
}
```
Expand Down Expand Up @@ -640,10 +640,10 @@ For example,
```c#
// Note: The attribute below identifies the 'Trip' table/container in the persistence store
[EntityName("Trip")]
public sealed class TripEntity : EntityBase
public sealed class Trip : EntityBase
{
// Note: This ctor must populate the entire internal state of the whole entity using properties that were rehydrated from the persistence store. Called by the 'Rehydrate()' method below
private TripEntity(Identifier identifier, IDependencyContainer container,
private Trip(Identifier identifier, IDependencyContainer container,
IReadOnlyDictionary<string, object> rehydratingProperties) : base(
identifier, container, rehydratingProperties)
{
Expand All @@ -656,9 +656,9 @@ public sealed class TripEntity : EntityBase
}

// Note: This method is called by the runtime when the entity is loaded from a persistence store
public static EntityFactory<TripEntity> Rehydrate()
public static EntityFactory<Trip> Rehydrate()
{
return (identifier, container, properties) => new TripEntity(identifier, container, properties);
return (identifier, container, properties) => new Trip(identifier, container, properties);
}

// Note: this method is called by the runtime when the entity is saved to a persistence store
Expand All @@ -683,10 +683,10 @@ public sealed class TripEntity : EntityBase
For example,

```c#
public sealed class UnavailabilityEntity : EntityBase
public sealed class Unavailability : EntityBase
{
// Note: This ctor only calls the base class. Called by the 'Create()' factory method
private UnavailabilityEntity(IRecorder recorder, IIdentifierFactory idFactory, RootEventHandler rootEventHandler) : base(recorder, idFactory, rootEventHandler)
private Unavailability(IRecorder recorder, IIdentifierFactory idFactory, RootEventHandler rootEventHandler) : base(recorder, idFactory, rootEventHandler)
{
}
```
Expand Down Expand Up @@ -714,7 +714,7 @@ For example,
{
if (BeganAt.HasValue)
{
return Error.RuleViolation(Resources.TripEntity_AlreadyBegan);
return Error.RuleViolation(Resources.Trip_AlreadyBegan);
}

var starts = DateTime.UtcNow;
Expand Down Expand Up @@ -742,17 +742,17 @@ For example:

if (BeganAt.HasValue && From.NotExists())
{
return Error.RuleViolation(Resources.TripEntity_NoStartingLocation);
return Error.RuleViolation(Resources.Trip_NoStartingLocation);
}

if (EndedAt.HasValue && !BeganAt.HasValue)
{
return Error.RuleViolation(Resources.TripEntity_NotBegun);
return Error.RuleViolation(Resources.Trip_NotBegun);
}

if (EndedAt.HasValue && To.NotExists())
{
return Error.RuleViolation(Resources.TripEntity_NoEndingLocation);
return Error.RuleViolation(Resources.Trip_NoEndingLocation);
}

return Result.Ok;
Expand Down
6 changes: 3 additions & 3 deletions src/AncillaryInfrastructure/AncillaryModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@

namespace AncillaryInfrastructure;

public class AncillaryModule : ISubDomainModule
public class AncillaryModule : ISubdomainModule
{
public Assembly ApiAssembly => typeof(UsagesApi).Assembly;
public Assembly InfrastructureAssembly => typeof(UsagesApi).Assembly;

public Assembly DomainAssembly => typeof(AuditRoot).Assembly;

public Dictionary<Type, string> AggregatePrefixes => new()
public Dictionary<Type, string> EntityPrefixes => new()
{
{ typeof(AuditRoot), "audit" },
{ typeof(EmailDeliveryRoot), "emaildelivery" }
Expand Down
8 changes: 4 additions & 4 deletions src/ApiHost1/ApiHostModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ namespace ApiHost1;
/// <summary>
/// Provides a module for common services of a API host
/// </summary>
public class ApiHostModule : ISubDomainModule
public class ApiHostModule : ISubdomainModule
{
public Assembly ApiAssembly => typeof(HealthApi).Assembly;
public Assembly InfrastructureAssembly => typeof(HealthApi).Assembly;

public Assembly DomainAssembly => null!;
public Assembly? DomainAssembly => null;

public Dictionary<Type, string> AggregatePrefixes => new();
public Dictionary<Type, string> EntityPrefixes => new();

public Action<WebApplication, List<MiddlewareRegistration>> ConfigureMiddleware
{
Expand Down
4 changes: 2 additions & 2 deletions src/ApiHost1/HostedModules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ namespace ApiHost1;

public static class HostedModules
{
public static SubDomainModules Get()
public static SubdomainModules Get()
{
var modules = new SubDomainModules();
var modules = new SubdomainModules();
modules.Register(new ApiHostModule());
modules.Register(new EndUsersModule());
modules.Register(new OrganizationsModule());
Expand Down
8 changes: 4 additions & 4 deletions src/ApiHost1/TestingOnlyApiModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@

namespace ApiHost1;

public class TestingOnlyApiModule : ISubDomainModule
public class TestingOnlyApiModule : ISubdomainModule
{
public Assembly ApiAssembly => typeof(TestingWebApi).Assembly;
public Assembly InfrastructureAssembly => typeof(TestingWebApi).Assembly;

public Assembly DomainAssembly => null!;
public Assembly? DomainAssembly => null;

public Dictionary<Type, string> AggregatePrefixes => new();
public Dictionary<Type, string> EntityPrefixes => new();

public Action<WebApplication, List<MiddlewareRegistration>> ConfigureMiddleware
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
namespace BookingsDomain.UnitTests;

[Trait("Category", "Unit")]
public class TripEntitySpec
public class TripSpec
{
private readonly TripEntity _trip;
private readonly Trip _trip;

public TripEntitySpec()
public TripSpec()
{
var recorder = new Mock<IRecorder>();
var idFactory = new FixedIdentifierFactory("anid");

_trip = TripEntity.Create(recorder.Object, idFactory, _ => Result.Ok).Value;
_trip = Trip.Create(recorder.Object, idFactory, _ => Result.Ok).Value;
_trip.RaiseChangeEvent(Events.TripAdded.Create("arootid".ToId(), "anorganizationid".ToId()));
}

Expand Down
4 changes: 2 additions & 2 deletions src/BookingsDomain.UnitTests/TripsSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public void WhenAdd_ThenAddsTrip()
{
var recorder = new Mock<IRecorder>();
var idFactory = new FixedIdentifierFactory("anid");
var trip = TripEntity.Create(recorder.Object, idFactory, _ => Result.Ok).Value;
var trip = Trip.Create(recorder.Object, idFactory, _ => Result.Ok).Value;

_trips.Add(trip);

Expand All @@ -37,7 +37,7 @@ public void WhenLatestAndSome_ThenReturnsLast()
{
var recorder = new Mock<IRecorder>();
var idFactory = new FixedIdentifierFactory("anid");
var trip = TripEntity.Create(recorder.Object, idFactory, _ => Result.Ok).Value;
var trip = Trip.Create(recorder.Object, idFactory, _ => Result.Ok).Value;
_trips.Add(trip);

var result = _trips.Latest();
Expand Down
2 changes: 1 addition & 1 deletion src/BookingsDomain/BookingRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ protected override Result<Error> OnStateChanged(IDomainEvent @event, bool isReco
case Events.TripAdded changed:
{
var trip = RaiseEventToChildEntity(isReconstituting, changed, idFactory =>
TripEntity.Create(Recorder, idFactory, RaiseChangeEvent), e => e.TripId!);
Trip.Create(Recorder, idFactory, RaiseChangeEvent), e => e.TripId!);
if (!trip.IsSuccessful)
{
return trip.Error;
Expand Down
14 changes: 7 additions & 7 deletions src/BookingsDomain/TripEntity.cs → src/BookingsDomain/Trip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@
namespace BookingsDomain;

[EntityName("Trip")]
public sealed class TripEntity : EntityBase
public sealed class Trip : EntityBase
{
public static Result<TripEntity, Error> Create(IRecorder recorder, IIdentifierFactory idFactory,
public static Result<Trip, Error> Create(IRecorder recorder, IIdentifierFactory idFactory,
RootEventHandler rootEventHandler)
{
return new TripEntity(recorder, idFactory, rootEventHandler);
return new Trip(recorder, idFactory, rootEventHandler);
}

private TripEntity(IRecorder recorder, IIdentifierFactory idFactory,
private Trip(IRecorder recorder, IIdentifierFactory idFactory,
RootEventHandler rootEventHandler) : base(recorder, idFactory, rootEventHandler)
{
}

private TripEntity(ISingleValueObject<string> identifier, IDependencyContainer container,
private Trip(ISingleValueObject<string> identifier, IDependencyContainer container,
HydrationProperties rehydratingProperties) : base(identifier, container, rehydratingProperties)
{
RootId = rehydratingProperties.GetValueOrDefault<Identifier>(nameof(RootId));
Expand All @@ -48,9 +48,9 @@ private TripEntity(ISingleValueObject<string> identifier, IDependencyContainer c

public Optional<Location> To { get; private set; }

public static EntityFactory<TripEntity> Rehydrate()
public static EntityFactory<Trip> Rehydrate()
{
return (identifier, container, properties) => new TripEntity(identifier, container, properties);
return (identifier, container, properties) => new Trip(identifier, container, properties);
}

public override HydrationProperties Dehydrate()
Expand Down
12 changes: 6 additions & 6 deletions src/BookingsDomain/Trips.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

namespace BookingsDomain;

public class Trips : IReadOnlyList<TripEntity>
public class Trips : IReadOnlyList<Trip>
{
private readonly List<TripEntity> _trips = new();
private readonly List<Trip> _trips = new();

public IEnumerator<TripEntity> GetEnumerator()
public IEnumerator<Trip> GetEnumerator()
{
return _trips.GetEnumerator();
}
Expand All @@ -18,14 +18,14 @@ IEnumerator IEnumerable.GetEnumerator()

public int Count => _trips.Count;

public TripEntity this[int index] => _trips[index];
public Trip this[int index] => _trips[index];

public void Add(TripEntity trip)
public void Add(Trip trip)
{
_trips.Add(trip);
}

public TripEntity? Latest()
public Trip? Latest()
{
return _trips.LastOrDefault();
}
Expand Down
8 changes: 4 additions & 4 deletions src/BookingsInfrastructure/BookingsModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@

namespace BookingsInfrastructure;

public class BookingsModule : ISubDomainModule
public class BookingsModule : ISubdomainModule
{
public Assembly ApiAssembly => typeof(BookingsApi).Assembly;
public Assembly InfrastructureAssembly => typeof(BookingsApi).Assembly;

public Assembly DomainAssembly => typeof(BookingRoot).Assembly;

public Dictionary<Type, string> AggregatePrefixes => new()
public Dictionary<Type, string> EntityPrefixes => new()
{
{ typeof(BookingRoot), "booking" },
{ typeof(TripEntity), "trip" }
{ typeof(Trip), "trip" }
};

public Action<WebApplication, List<MiddlewareRegistration>> ConfigureMiddleware
Expand Down
1 change: 1 addition & 0 deletions src/CarsApplication/CarsApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Common.Extensions;
using Domain.Common.Identity;
using Domain.Common.ValueObjects;
using Unavailability = Application.Resources.Shared.Unavailability;

namespace CarsApplication;

Expand Down
1 change: 1 addition & 0 deletions src/CarsApplication/Persistence/ICarRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using CarsDomain;
using Common;
using Domain.Common.ValueObjects;
using Unavailability = CarsApplication.Persistence.ReadModels.Unavailability;

namespace CarsApplication.Persistence;

Expand Down
2 changes: 1 addition & 1 deletion src/CarsDomain.UnitTests/CarRootSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public CarRootSpec()
identifierFactory.Setup(f => f.Create(It.IsAny<IIdentifiableEntity>()))
.Returns((IIdentifiableEntity e) =>
{
if (e is UnavailabilityEntity)
if (e is Unavailability)
{
return $"anunavailbilityid{++entityCount}".ToId();
}
Expand Down
Loading

0 comments on commit f22dcaa

Please sign in to comment.