Add project files.

This commit is contained in:
2025-09-01 13:34:36 +04:30
parent 1f2fb6e2d7
commit 81e43f5b92
83 changed files with 1733 additions and 0 deletions
@@ -0,0 +1,27 @@
namespace VizhTalk.BuildingBlocks.Domain.Contract;
public abstract record CommandBase<T> : ICommand<T>
{
public Guid Id { get; private set; }
protected CommandBase()
{
Id = Guid.NewGuid();
}
protected CommandBase(Guid id)
{
Id = id;
}
}
public abstract record CommandBase : ICommand
{
public Guid Id { get; private set; }
protected CommandBase()
{
Id = Guid.NewGuid();
}
protected CommandBase(Guid id)
{
Id = id;
}
}
@@ -0,0 +1,11 @@
namespace VizhTalk.BuildingBlocks.Domain.Contract;
public interface ICommand<out TResult>
{
Guid Id { get; }
}
public interface ICommand
{
Guid Id { get; }
}
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VizhTalk.BuildingBlocks.Domain.Contract
{
public interface IGuardException
{
}
}
@@ -0,0 +1,5 @@
namespace VizhTalk.BuildingBlocks.Domain.Contract;
public interface INotification
{
}
@@ -0,0 +1,5 @@
namespace VizhTalk.BuildingBlocks.Domain.Contract;
public interface IQuery<out TResult>
{
}
@@ -0,0 +1,14 @@
namespace VizhTalk.BuildingBlocks.Domain;
public class DomainEventBase : IDomainEvent
{
public Guid Id { get; }
public DateTime OccurredOn { get; }
public DomainEventBase()
{
this.Id = Guid.NewGuid();
this.OccurredOn = DateTime.UtcNow;
}
}
+40
View File
@@ -0,0 +1,40 @@
using VizhTalk.BuildingBlocks.Domain.Exceptions;
namespace VizhTalk.BuildingBlocks.Domain;
public abstract class Entity<T>
where T : ITypeIdValueBase
{
public Entity()
{
IsDeleted = false;
IsActive = true;
}
public T Id { get; protected set; }
public bool IsDeleted { get; protected set; }
public bool IsActive { get; protected set; }
private List<IDomainEvent> _domainEvents;
public void ClearDomainEvents()
{
_domainEvents?.Clear();
}
protected void AddDomainEvent(IDomainEvent domainEvent)
{
_domainEvents ??= [];
this._domainEvents.Add(domainEvent);
}
public IReadOnlyList<IDomainEvent> DomainEvents => _domainEvents;
protected void CheckRule(IBusinessRule rule)
{
if (rule.IsBroken())
{
throw new BusinessRuleValidationException(rule);
}
}
}
@@ -0,0 +1,20 @@
namespace VizhTalk.BuildingBlocks.Domain.Exceptions;
public class BusinessRuleValidationException : Exception
{
public IBusinessRule BrokenRule { get; }
public string Details { get; }
public BusinessRuleValidationException(IBusinessRule brokenRule)
: base(brokenRule.Message)
{
BrokenRule = brokenRule;
this.Details = brokenRule.Message;
}
public override string ToString()
{
return $"{BrokenRule.GetType().FullName}: {BrokenRule.Message}";
}
}
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VizhTalk.BuildingBlocks.Domain.Contract;
namespace VizhTalk.BuildingBlocks.Domain.Exceptions.GuardExceptions;
public class NullOrEmptyException(string message) : Exception(message), IGuardException
{
}
@@ -0,0 +1,8 @@
namespace VizhTalk.BuildingBlocks.Domain.Exceptions;
public interface IBusinessRule
{
bool IsBroken();
string Message { get; }
}
@@ -0,0 +1,9 @@
namespace VizhTalk.BuildingBlocks.Domain.Exceptions;
public class ValueObjectValidationException : Exception
{
public ValueObjectValidationException(string message)
:base(message)
{
}
}
@@ -0,0 +1,8 @@
namespace VizhTalk.BuildingBlocks.Domain.Guards
{
public static class Guard
{
public static void NullOrEmpty(this string value, string name)
=> StringGuard.NullOrEmpty(value, name);
}
}
@@ -0,0 +1,12 @@
using VizhTalk.BuildingBlocks.Domain.Exceptions.GuardExceptions;
namespace VizhTalk.BuildingBlocks.Domain.Guards;
internal static class StringGuard
{
internal static void NullOrEmpty(string value,string name)
{
if(string.IsNullOrEmpty(value))
throw new NullOrEmptyException($"{name} cannot be empty");
}
}
@@ -0,0 +1,7 @@
namespace VizhTalk.BuildingBlocks.Domain;
public interface IAggregateRoot
{
}
@@ -0,0 +1,12 @@
using VizhTalk.BuildingBlocks.Domain.Contract;
namespace VizhTalk.BuildingBlocks.Domain
{
public interface IDomainEvent : INotification
{
Guid Id { get; }
DateTime OccurredOn { get; }
}
}
@@ -0,0 +1,10 @@
namespace VizhTalk.BuildingBlocks.Domain;
public interface IRepositoryBase<TDomain, TId>
where TDomain : Entity<TId> where TId : ITypeIdValueBase
{
Task<TDomain> CreateAsync(TDomain entity, CancellationToken cancellationToken = default);
Task<TDomain> UpdateAsync(TDomain entity, CancellationToken cancellationToken = default);
Task DeleteAsync(TId id, CancellationToken cancellationToken = default);
Task<TDomain> GetByIdAsync(TId id, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,6 @@
namespace VizhTalk.BuildingBlocks.Domain;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class IgnoreMemberAttribute : Attribute
{
}
@@ -0,0 +1,59 @@
namespace VizhTalk.BuildingBlocks.Domain;
public abstract class TypedIdValueBase<T> : IEquatable<TypedIdValueBase<T>> , ITypeIdValueBase
{
public T Value { get; }
protected TypedIdValueBase(T value)
{
if (EqualityComparer<T>.Default.Equals(value, default(T)))
{
throw new InvalidOperationException($"Id value cannot be empty ! : id is {value}");
}
Value = value;
}
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
return obj is TypedIdValueBase<T> other && Equals(other);
}
public override int GetHashCode()
{
return Value!.GetHashCode();
}
public bool Equals(TypedIdValueBase<T>? other)
{
return EqualityComparer<T>.Default.Equals(this.Value, other.Value);
}
public static bool operator ==(TypedIdValueBase<T>? obj1, TypedIdValueBase<T>? obj2)
{
if (object.Equals(obj1, null))
{
if (object.Equals(obj2, null))
{
return true;
}
return false;
}
return obj1.Equals(obj2);
}
public static bool operator !=(TypedIdValueBase<T>? x, TypedIdValueBase<T>? y)
{
return !(x == y);
}
}
public interface ITypeIdValueBase { }
@@ -0,0 +1,123 @@
using System.Reflection;
using VizhTalk.BuildingBlocks.Domain.Exceptions;
namespace VizhTalk.BuildingBlocks.Domain;
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));
}
public override int GetHashCode()
{
unchecked
{
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;
}
}
protected static void CheckRule(IBusinessRule rule)
{
if (rule.IsBroken())
{
throw new BusinessRuleValidationException(rule);
}
}
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 | BindingFlags.NonPublic)
.Where(p => p.GetCustomAttribute(typeof(IgnoreMemberAttribute)) == null)
.ToList();
}
return this._fields;
}
private int HashValue(int seed, object value)
{
var currentHash = value?.GetHashCode() ?? 0;
return (seed * 23) + currentHash;
}
}
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>