Skip to content

Commit 37322ce

Browse files
Add a wrapper on DbContext and dbset<T>
Add an Interface marker for compile-time detection. add modelBuilder extension to register entities dynamically.
1 parent e06473c commit 37322ce

File tree

11 files changed

+100
-5
lines changed

11 files changed

+100
-5
lines changed

src/SwiftLink.Application/Common/Interfaces/IApplicationDbContext.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace SwiftLink.Application.Common.Interfaces;
1+
using SwiftLink.Domain.Common;
2+
3+
namespace SwiftLink.Application.Common.Interfaces;
24

35
/// <summary>
46
/// This interface facilitates communication between the application layer, infrastructure, and the DbContext.
@@ -11,4 +13,6 @@ public interface IApplicationDbContext
1113
/// <param name="cancellationToken"></param>
1214
/// <returns></returns>
1315
public Task<Result> SaveChangesAsync(CancellationToken cancellationToken = default);
16+
17+
DbSet<TEntity> Set<TEntity>() where TEntity : class, IEntity;
1418
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
global using Microsoft.EntityFrameworkCore;
2+
global using SwiftLink.Domain.Entities;
3+
global using SwiftLink.Shared;

src/SwiftLink.Application/SwiftLink.Application.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@
66
<Nullable>enable</Nullable>
77
</PropertyGroup>
88

9+
<ItemGroup>
10+
<PackageReference Include="MediatR" Version="12.2.0" />
11+
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" />
12+
</ItemGroup>
13+
914
<ItemGroup>
1015
<ProjectReference Include="..\SwiftLink.Domain\SwiftLink.Domain.csproj" />
16+
<ProjectReference Include="..\SwiftLink.Shared\SwiftLink.Shared.csproj" />
1117
</ItemGroup>
1218

1319
</Project>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace SwiftLink.Domain.Common;
2+
3+
/// <summary>
4+
/// This interface is a marker for DbSet and Compile-Time detection.
5+
/// </summary>
6+
public interface IEntity
7+
{
8+
}

src/SwiftLink.Domain/Entities/Link.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
/// This class is designed to store the original URL for each subscriber along with the link code and expiration time.
55
/// </summary>
66
[Entity]
7-
public class Link
7+
public class Link: IEntity
88
{
99
public int Id { get; set; }
1010
public int SubscriberId { get; set; }

src/SwiftLink.Domain/Entities/LinkVisit.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
/// This class is intended for analytics, providing insights into the number of users who clicked on a shortened link.
55
/// </summary>
66
[Entity]
7-
public class LinkVisit
7+
public class LinkVisit: IEntity
88
{
99
public long Id { get; set; }
1010

src/SwiftLink.Domain/Entities/Subscriber.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
/// Only these subscribers are allowed to insert a URL to obtain a shorter one.
55
/// </summary>
66
[Entity]
7-
public class Subscriber
7+
public class Subscriber: IEntity
88
{
99
public int Id { get; set; }
1010
public Guid Token { get; set; }
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using SwiftLink.Domain.Common;
2+
using SwiftLink.Infrastructure.Extensions;
3+
using System.Reflection;
4+
5+
namespace SwiftLink.Infrastructure.Context;
6+
7+
public class ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : DbContext(options), IApplicationDbContext
8+
{
9+
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
10+
{
11+
configurationBuilder.Properties<string>().HaveMaxLength(200);
12+
configurationBuilder.Properties<string>().AreUnicode(false);
13+
}
14+
15+
protected override void OnModelCreating(ModelBuilder modelBuilder)
16+
{
17+
modelBuilder.HasDefaultSchema("Base");
18+
modelBuilder.RegisterEntities(typeof(EntityAttribute).Assembly);
19+
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
20+
21+
foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
22+
relationship.DeleteBehavior = DeleteBehavior.NoAction;
23+
}
24+
25+
public new async Task<Result> SaveChangesAsync(CancellationToken cancellationToken = default)
26+
{
27+
try
28+
{
29+
return await base.SaveChangesAsync(cancellationToken) is 0 ?
30+
Result.Failure("Faile On Save into Database.") :
31+
Result.Success();
32+
}
33+
catch (Exception ex)
34+
{
35+
return Result.Failure(ex.InnerException.Message);
36+
}
37+
}
38+
39+
public new DbSet<TEntity> Set<TEntity>() where TEntity : class, IEntity
40+
=> base.Set<TEntity>();
41+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using SwiftLink.Domain.Common;
2+
using System.Reflection;
3+
4+
namespace SwiftLink.Infrastructure.Extensions;
5+
6+
/// <summary>
7+
/// This extention is programmed for registering Entities that are defined the EntityAttribute .
8+
/// </summary>
9+
public static class ModelBuilderExtention
10+
{
11+
public static void RegisterEntities(this ModelBuilder modelBuilder, params Assembly[] assemblies)
12+
{
13+
IEnumerable<Type> types = assemblies.SelectMany(x => x.GetExportedTypes())
14+
.Where(x => x.IsClass
15+
&& !x.IsAbstract
16+
&& x.IsPublic
17+
&& Attribute.IsDefined(x, typeof(EntityAttribute)));
18+
foreach (Type type in types)
19+
modelBuilder.Entity(type);
20+
}
21+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
global using Microsoft.EntityFrameworkCore;
2+
global using SwiftLink.Application.Common.Interfaces;
3+
global using SwiftLink.Domain.Entities;
4+
global using SwiftLink.Shared;

0 commit comments

Comments
 (0)