Skip to content

Commit 4d00350

Browse files
committed
Refactoring
- Remove MediatR - Update .Net9
1 parent f60ac11 commit 4d00350

File tree

11 files changed

+399
-11
lines changed

11 files changed

+399
-11
lines changed

Modular.Monolithic.Architecture.Helper.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Elementi di soluzione", "El
1010
.editorconfig = .editorconfig
1111
EndProjectSection
1212
EndProject
13+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modular.Monolithic.Architecture.Helper.Domain.Test", "test\Modular.Monolithic.Architecture.Helper.Domain.Test\Modular.Monolithic.Architecture.Helper.Domain.Test.csproj", "{2EEB3EA9-A09D-41DF-B700-16281D2CBA2B}"
14+
EndProject
1315
Global
1416
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1517
Debug|Any CPU = Debug|Any CPU
@@ -20,6 +22,10 @@ Global
2022
{08BAB259-27D2-4221-9689-7FF3158CB3E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
2123
{08BAB259-27D2-4221-9689-7FF3158CB3E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
2224
{08BAB259-27D2-4221-9689-7FF3158CB3E4}.Release|Any CPU.Build.0 = Release|Any CPU
25+
{2EEB3EA9-A09D-41DF-B700-16281D2CBA2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26+
{2EEB3EA9-A09D-41DF-B700-16281D2CBA2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
27+
{2EEB3EA9-A09D-41DF-B700-16281D2CBA2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
28+
{2EEB3EA9-A09D-41DF-B700-16281D2CBA2B}.Release|Any CPU.Build.0 = Release|Any CPU
2329
EndGlobalSection
2430
GlobalSection(SolutionProperties) = preSolution
2531
HideSolutionNode = FALSE
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
namespace Modular.Monolithic.Architecture.Helper.Domain.Core;
1+

2+
namespace Modular.Monolithic.Architecture.Helper.Domain.Core;
23

34
/// <summary>
4-
///
5+
/// Represents the base class that rappresent AggregateRoot.
56
/// </summary>
6-
public abstract class AggregateRoot : Entity { }
7+
public abstract class AggregateRoot : Entity
8+
{
9+
protected AggregateRoot(Guid id) : base(id)
10+
{
11+
}
12+
}

src/Modular.Monolithic.Architecture.Helper.Domain/Core/Entity.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Modular.Monolithic.Architecture.Helper.Domain.BusinessRules;
1+
using Modular.Monolithic.Architecture.Helper.Domain.Abstractions;
2+
using Modular.Monolithic.Architecture.Helper.Domain.BusinessRules;
23
using Modular.Monolithic.Architecture.Helper.Domain.Events;
34
using Modular.Monolithic.Architecture.Helper.Domain.Exceptions;
45

@@ -7,7 +8,7 @@ namespace Modular.Monolithic.Architecture.Helper.Domain.Core;
78
/// <summary>
89
/// Represents the base class that all entities derive from.
910
/// </summary>
10-
public abstract class Entity
11+
public abstract class Entity : TypedIdValueBase
1112
{
1213

1314
private List<IDomainEvent> _domainEvents;
@@ -16,14 +17,16 @@ public abstract class Entity
1617
/// Domain events occurred.
1718
/// </summary>
1819
public IReadOnlyCollection<IDomainEvent>? DomainEvents => _domainEvents?.AsReadOnly();
20+
1921
/// <summary>
2022
/// Initializes a new instance of the <see cref="Entity"/> class.
2123
/// </summary>
2224
/// <remarks>
2325
/// Required by EF Core.
2426
/// </remarks>
25-
protected Entity()
27+
protected Entity(Guid id) : base(id)
2628
{
29+
2730
}
2831
/// <summary>
2932
///
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
using System.Reflection;
2+
using Modular.Monolithic.Architecture.Helper.Domain.Maybe;
3+
4+
namespace Modular.Monolithic.Architecture.Helper.Domain.Core;
5+
/// <summary>
6+
/// Represents an enumeration type.
7+
/// </summary>
8+
/// <typeparam name="TEnum">The type of the enumeration.</typeparam>
9+
public abstract class Enumeration<TEnum> : IEquatable<Enumeration<TEnum>>, IComparable<Enumeration<TEnum>>
10+
where TEnum : Enumeration<TEnum>
11+
{
12+
private static readonly Lazy<Dictionary<int, TEnum>> EnumerationsDictionary =
13+
new Lazy<Dictionary<int, TEnum>>(() => GetAllEnumerationOptions().ToDictionary(item => item.Value));
14+
15+
/// <summary>
16+
/// Initializes a new instance of the <see cref="Enumeration{TEnum}"/> class.
17+
/// </summary>
18+
/// <param name="value">The value.</param>
19+
/// <param name="name">The name.</param>
20+
protected Enumeration(int value, string name)
21+
{
22+
Value = value;
23+
Name = name;
24+
}
25+
26+
/// <summary>
27+
/// Initializes a new instance of the <see cref="Enumeration{TEnum}"/> class.
28+
/// </summary>
29+
/// <remarks>
30+
/// Required by EF Core.
31+
/// </remarks>
32+
protected Enumeration()
33+
{
34+
Value = default;
35+
Name = string.Empty;
36+
}
37+
38+
/// <summary>
39+
/// Gets the enumeration values.
40+
/// </summary>
41+
/// <returns>The read-only collection of enumeration values.</returns>
42+
public static IReadOnlyCollection<TEnum> List => EnumerationsDictionary.Value.Values.ToList();
43+
44+
/// <summary>
45+
/// Gets the value.
46+
/// </summary>
47+
public int Value { get; private set; }
48+
49+
/// <summary>
50+
/// Gets the name.
51+
/// </summary>
52+
public string Name { get; private set; }
53+
54+
/// <summary>
55+
/// Creates an enumeration of the specified type based on the specified value.
56+
/// </summary>
57+
/// <param name="value">The enumeration value.</param>
58+
/// <returns>The enumeration instance that matches the specified value.</returns>
59+
public static Maybe<TEnum> FromValue(int value) => EnumerationsDictionary.Value.TryGetValue(value, out TEnum enumeration)
60+
? Maybe<TEnum>.From(enumeration)
61+
: Maybe<TEnum>.None;
62+
63+
/// <summary>
64+
/// Checks if the there is an enumeration with the specified value.
65+
/// </summary>
66+
/// <param name="value">The value.</param>
67+
/// <returns>True if there is an enumeration with the specified value, otherwise false.</returns>
68+
public static bool ContainsValue(int value) => EnumerationsDictionary.Value.ContainsKey(value);
69+
70+
public static bool operator ==(Enumeration<TEnum> a, Enumeration<TEnum> b)
71+
{
72+
if (a is null && b is null)
73+
{
74+
return true;
75+
}
76+
77+
if (a is null || b is null)
78+
{
79+
return false;
80+
}
81+
82+
return a.Equals(b);
83+
}
84+
85+
public static bool operator !=(Enumeration<TEnum> a, Enumeration<TEnum> b) => !(a == b);
86+
87+
/// <inheritdoc />
88+
public bool Equals(Enumeration<TEnum> other)
89+
{
90+
if (other is null)
91+
{
92+
return false;
93+
}
94+
95+
return GetType() == other.GetType() && other.Value.Equals(Value);
96+
}
97+
98+
/// <inheritdoc />
99+
public override bool Equals(object obj)
100+
{
101+
if (obj is null)
102+
{
103+
return false;
104+
}
105+
106+
if (!(obj is Enumeration<TEnum> otherValue))
107+
{
108+
return false;
109+
}
110+
111+
return GetType() == obj.GetType() && otherValue.Value.Equals(Value);
112+
}
113+
114+
/// <inheritdoc />
115+
public int CompareTo(Enumeration<TEnum> other) => other is null ? 1 : Value.CompareTo(other.Value);
116+
117+
/// <inheritdoc />
118+
public override int GetHashCode() => Value.GetHashCode();
119+
120+
/// <summary>
121+
/// Gets all of the defined enumeration options.
122+
/// </summary>
123+
/// <returns>The enumerable collection of enumerations.</returns>
124+
private static IEnumerable<TEnum> GetAllEnumerationOptions()
125+
{
126+
Type enumType = typeof(TEnum);
127+
128+
IEnumerable<Type> enumerationTypes = Assembly
129+
.GetAssembly(enumType)!
130+
.GetTypes()
131+
.Where(type => enumType.IsAssignableFrom(type));
132+
133+
var enumerations = new List<TEnum>();
134+
135+
foreach (Type enumerationType in enumerationTypes)
136+
{
137+
List<TEnum> enumerationTypeOptions = GetFieldsOfType<TEnum>(enumerationType);
138+
139+
enumerations.AddRange(enumerationTypeOptions);
140+
}
141+
142+
return enumerations;
143+
}
144+
145+
/// <summary>
146+
/// Gets the fields of the specified type for the specified type.
147+
/// </summary>
148+
/// <typeparam name="TFieldType">The field type.</typeparam>
149+
/// <param name="type">The type whose fields are being retrieved.</param>
150+
/// <returns>The fields of the specified type for the specified type.</returns>
151+
private static List<TFieldType> GetFieldsOfType<TFieldType>(Type type) =>
152+
type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
153+
.Where(fieldInfo => type.IsAssignableFrom(fieldInfo.FieldType))
154+
.Select(fieldInfo => (TFieldType)fieldInfo.GetValue(null))
155+
.ToList();
156+
}

src/Modular.Monolithic.Architecture.Helper.Domain/Events/IDomainEvent.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
using MediatR;
2-
1+

32
namespace Modular.Monolithic.Architecture.Helper.Domain.Events;
43

54
/// <summary>
65
/// Represents the interface for an event that is raised within the domain.
76
/// </summary>
8-
public interface IDomainEvent : INotification
7+
public interface IDomainEvent
98
{
109
Guid Id { get; }
1110

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
namespace Modular.Monolithic.Architecture.Helper.Domain.Maybe;
2+
/// <summary>
3+
/// Represents a wrapper around a value that may or may not be null.
4+
/// </summary>
5+
/// <typeparam name="T">The value type.</typeparam>
6+
public sealed class Maybe<T> : IEquatable<Maybe<T>>
7+
{
8+
private readonly T _value;
9+
10+
/// <summary>
11+
/// Initializes a new instance of the <see cref="Maybe{T}"/> class.
12+
/// </summary>
13+
/// <param name="value">The value.</param>
14+
private Maybe(T value) => _value = value;
15+
16+
/// <summary>
17+
/// Gets a value indicating whether or not the value exists.
18+
/// </summary>
19+
public bool HasValue => !HasNoValue;
20+
21+
/// <summary>
22+
/// Gets a value indicating whether or not the value does not exist.
23+
/// </summary>
24+
public bool HasNoValue => _value is null;
25+
26+
/// <summary>
27+
/// Gets the value.
28+
/// </summary>
29+
public T Value => HasValue
30+
? _value
31+
: throw new InvalidOperationException("The value can not be accessed because it does not exist.");
32+
33+
/// <summary>
34+
/// Gets the default empty instance.
35+
/// </summary>
36+
public static Maybe<T> None => new Maybe<T>(default);
37+
38+
/// <summary>
39+
/// Creates a new <see cref="Maybe{T}"/> instance based on the specified value.
40+
/// </summary>
41+
/// <param name="value">The value.</param>
42+
/// <returns>The new <see cref="Maybe{T}"/> instance.</returns>
43+
public static Maybe<T> From(T value) => new Maybe<T>(value);
44+
45+
public static implicit operator Maybe<T>(T value) => From(value);
46+
47+
public static implicit operator T(Maybe<T> maybe) => maybe.Value;
48+
49+
/// <inheritdoc />
50+
public bool Equals(Maybe<T> other)
51+
{
52+
if (other is null)
53+
{
54+
return false;
55+
}
56+
57+
if (HasNoValue && other.HasNoValue)
58+
{
59+
return true;
60+
}
61+
62+
if (HasNoValue || other.HasNoValue)
63+
{
64+
return false;
65+
}
66+
67+
return Value.Equals(other.Value);
68+
}
69+
70+
/// <inheritdoc />
71+
public override bool Equals(object obj) =>
72+
obj switch
73+
{
74+
null => false,
75+
T value => Equals(new Maybe<T>(value)),
76+
Maybe<T> maybe => Equals(maybe),
77+
_ => false
78+
};
79+
80+
/// <inheritdoc />
81+
public override int GetHashCode() => HasValue ? Value.GetHashCode() : 0;
82+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
namespace Modular.Monolithic.Architecture.Helper.Domain.Maybe;
2+
3+
/// <summary>
4+
/// Contains extension methods for the maybe class.
5+
/// </summary>
6+
public static class MaybeExtensions
7+
{
8+
/// <summary>
9+
/// Binds to the result of the function and returns it.
10+
/// </summary>
11+
/// <typeparam name="TIn">The result type.</typeparam>
12+
/// <typeparam name="TOut">The output result type.</typeparam>
13+
/// <param name="maybe">The result.</param>
14+
/// <param name="func">The bind function.</param>
15+
/// <returns>
16+
/// The success result with the bound value if the current result is a success result, otherwise a failure result.
17+
/// </returns>
18+
public static async Task<Maybe<TOut>> Bind<TIn, TOut>(this Maybe<TIn> maybe, Func<TIn, Task<Maybe<TOut>>> func) =>
19+
maybe.HasValue ? await func(maybe.Value) : Maybe<TOut>.None;
20+
21+
/// <summary>
22+
/// Matches to the corresponding functions based on existence of the value.
23+
/// </summary>
24+
/// <typeparam name="TIn">The input type.</typeparam>
25+
/// <typeparam name="TOut">The output type.</typeparam>
26+
/// <param name="resultTask">The maybe task.</param>
27+
/// <param name="onSuccess">The on-success function.</param>
28+
/// <param name="onFailure">The on-failure function.</param>
29+
/// <returns>
30+
/// The result of the on-success function if the maybe has a value, otherwise the result of the failure result.
31+
/// </returns>
32+
public static async Task<TOut> Match<TIn, TOut>(
33+
this Task<Maybe<TIn>> resultTask,
34+
Func<TIn, TOut> onSuccess,
35+
Func<TOut> onFailure)
36+
{
37+
var maybe = await resultTask;
38+
39+
return maybe.HasValue ? onSuccess(maybe.Value) : onFailure();
40+
}
41+
}

src/Modular.Monolithic.Architecture.Helper.Domain/Modular.Monolithic.Architecture.Helper.Domain.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
4+
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
@@ -23,7 +23,6 @@
2323
</PropertyGroup>
2424

2525
<ItemGroup>
26-
<PackageReference Include="MediatR" Version="12.3.0" />
2726
<PackageReference Include="Nerdbank.GitVersioning" Version="3.6.133">
2827
<PrivateAssets>all</PrivateAssets>
2928
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

0 commit comments

Comments
 (0)