first commit
This commit is contained in:
12
MyNewProjectName.Domain/Common/AuditableEntity.cs
Normal file
12
MyNewProjectName.Domain/Common/AuditableEntity.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace MyNewProjectName.Domain.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Base entity with audit properties
|
||||
/// </summary>
|
||||
public abstract class AuditableEntity : BaseEntity
|
||||
{
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public string? CreatedBy { get; set; }
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
public string? UpdatedBy { get; set; }
|
||||
}
|
||||
36
MyNewProjectName.Domain/Common/BaseEntity.cs
Normal file
36
MyNewProjectName.Domain/Common/BaseEntity.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
namespace MyNewProjectName.Domain.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Base entity with common properties for all entities
|
||||
/// </summary>
|
||||
public abstract class BaseEntity
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
private readonly List<IDomainEvent> _domainEvents = new();
|
||||
|
||||
public IReadOnlyCollection<IDomainEvent> DomainEvents => _domainEvents.AsReadOnly();
|
||||
|
||||
public void AddDomainEvent(IDomainEvent domainEvent)
|
||||
{
|
||||
_domainEvents.Add(domainEvent);
|
||||
}
|
||||
|
||||
public void RemoveDomainEvent(IDomainEvent domainEvent)
|
||||
{
|
||||
_domainEvents.Remove(domainEvent);
|
||||
}
|
||||
|
||||
public void ClearDomainEvents()
|
||||
{
|
||||
_domainEvents.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marker interface for domain events
|
||||
/// </summary>
|
||||
public interface IDomainEvent
|
||||
{
|
||||
DateTime OccurredOn { get; }
|
||||
}
|
||||
11
MyNewProjectName.Domain/Common/ISoftDelete.cs
Normal file
11
MyNewProjectName.Domain/Common/ISoftDelete.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace MyNewProjectName.Domain.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Interface for soft delete functionality
|
||||
/// </summary>
|
||||
public interface ISoftDelete
|
||||
{
|
||||
bool IsDeleted { get; set; }
|
||||
DateTime? DeletedAt { get; set; }
|
||||
string? DeletedBy { get; set; }
|
||||
}
|
||||
13
MyNewProjectName.Domain/Entities/SampleEntity.cs
Normal file
13
MyNewProjectName.Domain/Entities/SampleEntity.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using MyNewProjectName.Domain.Common;
|
||||
|
||||
namespace MyNewProjectName.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Sample entity - Replace with your actual entity
|
||||
/// </summary>
|
||||
public class SampleEntity : AuditableEntity
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
11
MyNewProjectName.Domain/Events/BaseDomainEvent.cs
Normal file
11
MyNewProjectName.Domain/Events/BaseDomainEvent.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using MyNewProjectName.Domain.Common;
|
||||
|
||||
namespace MyNewProjectName.Domain.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Base domain event
|
||||
/// </summary>
|
||||
public abstract class BaseDomainEvent : IDomainEvent
|
||||
{
|
||||
public DateTime OccurredOn { get; } = DateTime.UtcNow;
|
||||
}
|
||||
21
MyNewProjectName.Domain/Exceptions/DomainException.cs
Normal file
21
MyNewProjectName.Domain/Exceptions/DomainException.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace MyNewProjectName.Domain.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Base exception for domain layer
|
||||
/// </summary>
|
||||
public class DomainException : Exception
|
||||
{
|
||||
public DomainException()
|
||||
{
|
||||
}
|
||||
|
||||
public DomainException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public DomainException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
27
MyNewProjectName.Domain/Exceptions/NotFoundException.cs
Normal file
27
MyNewProjectName.Domain/Exceptions/NotFoundException.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace MyNewProjectName.Domain.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Exception thrown when an entity is not found
|
||||
/// </summary>
|
||||
public class NotFoundException : DomainException
|
||||
{
|
||||
public NotFoundException()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
public NotFoundException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public NotFoundException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
public NotFoundException(string name, object key)
|
||||
: base($"Entity \"{name}\" ({key}) was not found.")
|
||||
{
|
||||
}
|
||||
}
|
||||
27
MyNewProjectName.Domain/Exceptions/ValidationException.cs
Normal file
27
MyNewProjectName.Domain/Exceptions/ValidationException.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace MyNewProjectName.Domain.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Exception thrown when validation fails
|
||||
/// </summary>
|
||||
public class ValidationException : DomainException
|
||||
{
|
||||
public IDictionary<string, string[]> Errors { get; }
|
||||
|
||||
public ValidationException()
|
||||
: base("One or more validation failures have occurred.")
|
||||
{
|
||||
Errors = new Dictionary<string, string[]>();
|
||||
}
|
||||
|
||||
public ValidationException(string message)
|
||||
: base(message)
|
||||
{
|
||||
Errors = new Dictionary<string, string[]>();
|
||||
}
|
||||
|
||||
public ValidationException(IDictionary<string, string[]> errors)
|
||||
: base("One or more validation failures have occurred.")
|
||||
{
|
||||
Errors = errors;
|
||||
}
|
||||
}
|
||||
24
MyNewProjectName.Domain/Interfaces/IRepository.cs
Normal file
24
MyNewProjectName.Domain/Interfaces/IRepository.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Linq.Expressions;
|
||||
using MyNewProjectName.Domain.Common;
|
||||
|
||||
namespace MyNewProjectName.Domain.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Generic repository interface
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Entity type</typeparam>
|
||||
public interface IRepository<T> where T : BaseEntity
|
||||
{
|
||||
Task<T?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default);
|
||||
Task<IEnumerable<T>> GetAllAsync(CancellationToken cancellationToken = default);
|
||||
Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default);
|
||||
Task<T?> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default);
|
||||
Task<bool> AnyAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default);
|
||||
Task<int> CountAsync(Expression<Func<T, bool>>? predicate = null, CancellationToken cancellationToken = default);
|
||||
Task AddAsync(T entity, CancellationToken cancellationToken = default);
|
||||
Task AddRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken = default);
|
||||
void Update(T entity);
|
||||
void UpdateRange(IEnumerable<T> entities);
|
||||
void Remove(T entity);
|
||||
void RemoveRange(IEnumerable<T> entities);
|
||||
}
|
||||
12
MyNewProjectName.Domain/Interfaces/IUnitOfWork.cs
Normal file
12
MyNewProjectName.Domain/Interfaces/IUnitOfWork.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace MyNewProjectName.Domain.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Unit of Work pattern interface
|
||||
/// </summary>
|
||||
public interface IUnitOfWork : IDisposable
|
||||
{
|
||||
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
|
||||
Task BeginTransactionAsync(CancellationToken cancellationToken = default);
|
||||
Task CommitTransactionAsync(CancellationToken cancellationToken = default);
|
||||
Task RollbackTransactionAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
9
MyNewProjectName.Domain/MyNewProjectName.Domain.csproj
Normal file
9
MyNewProjectName.Domain/MyNewProjectName.Domain.csproj
Normal file
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
43
MyNewProjectName.Domain/ValueObjects/ValueObject.cs
Normal file
43
MyNewProjectName.Domain/ValueObjects/ValueObject.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
namespace MyNewProjectName.Domain.ValueObjects;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for value objects
|
||||
/// </summary>
|
||||
public abstract class ValueObject
|
||||
{
|
||||
protected abstract IEnumerable<object?> GetEqualityComponents();
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj == null || obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var other = (ValueObject)obj;
|
||||
return GetEqualityComponents().SequenceEqual(other.GetEqualityComponents());
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return GetEqualityComponents()
|
||||
.Select(x => x?.GetHashCode() ?? 0)
|
||||
.Aggregate((x, y) => x ^ y);
|
||||
}
|
||||
|
||||
public static bool operator ==(ValueObject? left, ValueObject? right)
|
||||
{
|
||||
if (left is null && right is null)
|
||||
return true;
|
||||
|
||||
if (left is null || right is null)
|
||||
return false;
|
||||
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(ValueObject? left, ValueObject? right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user