Add project files.

This commit is contained in:
2022-10-06 16:53:07 +03:00
parent 45fac5e086
commit 6f3acce7d4
38 changed files with 1051 additions and 0 deletions
@@ -0,0 +1,7 @@
namespace PracticeCalendar.Domain.Common
{
public class DomainEventBase
{
public DateTime EventDate { get; protected set; } = DateTime.UtcNow;
}
}
@@ -0,0 +1,6 @@
namespace PracticeCalendar.Domain.Common
{
public abstract class DomainException : Exception
{
}
}
@@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace PracticeCalendar.Domain.Common
{
public abstract class EntityBase
{
public int Id { get; set; }
private List<DomainEventBase> _domainEvents = new();
[NotMapped]
public IEnumerable<DomainEventBase> DomainEvents => _domainEvents.AsReadOnly();
protected void RegisterDomainEvent(DomainEventBase domainEvent) => _domainEvents.Add(domainEvent);
internal void ClearDomainEvents() => _domainEvents.Clear();
}
}
@@ -0,0 +1,8 @@
namespace PracticeCalendar.Domain.Common
{
// source: https://github.com/jhewlett/ValueObject
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class IgnoreMemberAttribute : Attribute
{
}
}
@@ -0,0 +1,6 @@
namespace PracticeCalendar.Domain.Common.Interfaces
{
// Apply this marker interface only to aggregate root entities
// Repositories will only work with aggregate roots, not their children
public interface IAggregateRoot { }
}
@@ -0,0 +1,8 @@
using Ardalis.Specification;
namespace PracticeCalendar.Domain.Common.Interfaces
{
public interface IRepository<T> : IRepositoryBase<T> where T : class, IAggregateRoot
{
}
}
@@ -0,0 +1,110 @@
using System.Reflection;
namespace PracticeCalendar.Domain.Common
{
// source: https://github.com/jhewlett/ValueObject
public abstract class ValueObject : IEquatable<ValueObject>
{
private List<PropertyInfo>? properties;
private List<FieldInfo>? fields;
public static bool operator ==(ValueObject? obj1, ValueObject? obj2)
{
if (object.Equals(obj1, null))
{
if (object.Equals(obj2, null))
{
return true;
}
return false;
}
return obj1.Equals(obj2);
}
public static bool operator !=(ValueObject? obj1, ValueObject? obj2)
{
return !(obj1 == obj2);
}
public bool Equals(ValueObject? obj)
{
return Equals(obj as object);
}
public override bool Equals(object? obj)
{
if (obj == null || GetType() != obj.GetType()) return false;
return GetProperties().All(p => PropertiesAreEqual(obj, p))
&& GetFields().All(f => FieldsAreEqual(obj, f));
}
private bool PropertiesAreEqual(object obj, PropertyInfo p)
{
return object.Equals(p.GetValue(this, null), p.GetValue(obj, null));
}
private bool FieldsAreEqual(object obj, FieldInfo f)
{
return object.Equals(f.GetValue(this), f.GetValue(obj));
}
private IEnumerable<PropertyInfo> GetProperties()
{
if (this.properties == null)
{
this.properties = GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.GetCustomAttribute(typeof(IgnoreMemberAttribute)) == null)
.ToList();
// Not available in Core
// !Attribute.IsDefined(p, typeof(IgnoreMemberAttribute))).ToList();
}
return this.properties;
}
private IEnumerable<FieldInfo> GetFields()
{
if (this.fields == null)
{
this.fields = GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.GetCustomAttribute(typeof(IgnoreMemberAttribute)) == null)
.ToList();
}
return this.fields;
}
public override int GetHashCode()
{
unchecked //allow overflow
{
int hash = 17;
foreach (var prop in GetProperties())
{
var value = prop.GetValue(this, null);
hash = HashValue(hash, value);
}
foreach (var field in GetFields())
{
var value = field.GetValue(this);
hash = HashValue(hash, value);
}
return hash;
}
}
private int HashValue(int seed, object? value)
{
var currentHash = value != null
? value.GetHashCode()
: 0;
return seed * 23 + currentHash;
}
}
}