Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<!--#endif-->
<PackageVersion Include="Aspire.Hosting.AppHost" Version="$(AspireVersion)" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Identity.Stores" Version="9.0.6" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="9.0.0" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.10.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.10.0" />
Expand Down
2 changes: 1 addition & 1 deletion src/Domain/Common/BaseAuditableEntity.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace CleanArchitecture.Domain.Common;

public abstract class BaseAuditableEntity : BaseEntity
public abstract class BaseAuditableEntity : IAuditableEntity
{
public DateTimeOffset Created { get; set; }

Expand Down
2 changes: 1 addition & 1 deletion src/Domain/Common/BaseEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace CleanArchitecture.Domain.Common;

public abstract class BaseEntity
public abstract class BaseEntity : BaseAuditableEntity, IDomainEvent
{
// This can easily be modified to be BaseEntity<T> and public T Id to support different key types.
// Using non-generic integer types for simplicity
Expand Down
4 changes: 1 addition & 3 deletions src/Domain/Common/BaseEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@

namespace CleanArchitecture.Domain.Common;

public abstract class BaseEvent : INotification
{
}
public record BaseEvent : INotification;
11 changes: 11 additions & 0 deletions src/Domain/Common/IAuditableEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace CleanArchitecture.Domain.Common;
public interface IAuditableEntity
{
DateTimeOffset Created { get; set; }

string? CreatedBy { get; set; }

DateTimeOffset LastModified { get; set; }

string? LastModifiedBy { get; set; }
}
11 changes: 11 additions & 0 deletions src/Domain/Common/IDomainEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace CleanArchitecture.Domain.Common;
public interface IDomainEvent
{
IReadOnlyCollection<BaseEvent> DomainEvents { get; }

void AddDomainEvent(BaseEvent domainEvent);

void RemoveDomainEvent(BaseEvent domainEvent);

void ClearDomainEvents();
}
1 change: 1 addition & 0 deletions src/Domain/Domain.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

<ItemGroup>
<PackageReference Include="MediatR" />
<PackageReference Include="Microsoft.Extensions.Identity.Stores" />
</ItemGroup>

</Project>
31 changes: 31 additions & 0 deletions src/Domain/Entities/ApplicationUser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.AspNetCore.Identity;

namespace CleanArchitecture.Domain.Entities;
public class ApplicationUser : IdentityUser, IAuditableEntity, IDomainEvent
{
public DateTimeOffset Created { get; set; }
public string? CreatedBy { get; set; }
public DateTimeOffset LastModified { get; set; }
public string? LastModifiedBy { get; set; }

private readonly List<BaseEvent> _domainEvents = [];

[NotMapped]
public IReadOnlyCollection<BaseEvent> DomainEvents => _domainEvents.AsReadOnly();

public void AddDomainEvent(BaseEvent domainEvent)
{
_domainEvents.Add(domainEvent);
}

public void ClearDomainEvents()
{
_domainEvents.Clear();
}

public void RemoveDomainEvent(BaseEvent domainEvent)
{
_domainEvents.Remove(domainEvent);
}
}
2 changes: 1 addition & 1 deletion src/Domain/Entities/TodoItem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace CleanArchitecture.Domain.Entities;

public class TodoItem : BaseAuditableEntity
public class TodoItem : BaseEntity
{
public int ListId { get; set; }

Expand Down
2 changes: 1 addition & 1 deletion src/Domain/Entities/TodoList.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace CleanArchitecture.Domain.Entities;

public class TodoList : BaseAuditableEntity
public class TodoList : BaseEntity
{
public string? Title { get; set; }

Expand Down
10 changes: 1 addition & 9 deletions src/Domain/Events/TodoItemCompletedEvent.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
namespace CleanArchitecture.Domain.Events;

public class TodoItemCompletedEvent : BaseEvent
{
public TodoItemCompletedEvent(TodoItem item)
{
Item = item;
}

public TodoItem Item { get; }
}
public record TodoItemCompletedEvent(TodoItem Item) : BaseEvent;
10 changes: 1 addition & 9 deletions src/Domain/Events/TodoItemCreatedEvent.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
namespace CleanArchitecture.Domain.Events;

public class TodoItemCreatedEvent : BaseEvent
{
public TodoItemCreatedEvent(TodoItem item)
{
Item = item;
}

public TodoItem Item { get; }
}
public record TodoItemCreatedEvent(TodoItem Item) : BaseEvent;
10 changes: 1 addition & 9 deletions src/Domain/Events/TodoItemDeletedEvent.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
namespace CleanArchitecture.Domain.Events;

public class TodoItemDeletedEvent : BaseEvent
{
public TodoItemDeletedEvent(TodoItem item)
{
Item = item;
}

public TodoItem Item { get; }
}
public record TodoItemDeletedEvent(TodoItem Item) : BaseEvent;
1 change: 0 additions & 1 deletion src/Infrastructure/Data/ApplicationDbContext.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Reflection;
using CleanArchitecture.Application.Common.Interfaces;
using CleanArchitecture.Domain.Entities;
using CleanArchitecture.Infrastructure.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

Expand Down
1 change: 0 additions & 1 deletion src/Infrastructure/Data/ApplicationDbContextInitialiser.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using CleanArchitecture.Domain.Constants;
using CleanArchitecture.Domain.Entities;
using CleanArchitecture.Infrastructure.Identity;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void UpdateEntities(DbContext? context)
{
if (context == null) return;

foreach (var entry in context.ChangeTracker.Entries<BaseAuditableEntity>())
foreach (var entry in context.ChangeTracker.Entries<IAuditableEntity>())
{
if (entry.State is EntityState.Added or EntityState.Modified || entry.HasChangedOwnedEntities())
{
Expand All @@ -46,7 +46,7 @@ public void UpdateEntities(DbContext? context)
{
entry.Entity.CreatedBy = _user.Id;
entry.Entity.Created = utcNow;
}
}
entry.Entity.LastModifiedBy = _user.Id;
entry.Entity.LastModified = utcNow;
}
Expand All @@ -57,8 +57,8 @@ public void UpdateEntities(DbContext? context)
public static class Extensions
{
public static bool HasChangedOwnedEntities(this EntityEntry entry) =>
entry.References.Any(r =>
r.TargetEntry != null &&
r.TargetEntry.Metadata.IsOwned() &&
entry.References.Any(r =>
r.TargetEntry != null &&
r.TargetEntry.Metadata.IsOwned() &&
(r.TargetEntry.State == EntityState.Added || r.TargetEntry.State == EntityState.Modified));
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public async Task DispatchDomainEvents(DbContext? context)
if (context == null) return;

var entities = context.ChangeTracker
.Entries<BaseEntity>()
.Entries<IDomainEvent>()
.Where(e => e.Entity.DomainEvents.Any())
.Select(e => e.Entity);

Expand Down
Loading
Loading