Skip to content

Commit 31f2662

Browse files
committed
Use DbContextFactory (fixes #45)
1 parent 9ab463b commit 31f2662

File tree

3 files changed

+25
-10
lines changed

3 files changed

+25
-10
lines changed

src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Repository.cs

+7-3
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@ namespace LinkDotNet.Blog.Infrastructure.Persistence.Sql;
1111
public class Repository<TEntity> : IRepository<TEntity>
1212
where TEntity : Entity
1313
{
14-
private readonly BlogDbContext blogDbContext;
14+
private readonly IDbContextFactory<BlogDbContext> dbContextFactory;
1515

16-
public Repository(BlogDbContext blogDbContext)
16+
public Repository(IDbContextFactory<BlogDbContext> dbContextFactory)
1717
{
18-
this.blogDbContext = blogDbContext;
18+
this.dbContextFactory = dbContextFactory;
1919
}
2020

2121
public async ValueTask<TEntity> GetByIdAsync(string id)
2222
{
23+
await using var blogDbContext = await dbContextFactory.CreateDbContextAsync();
2324
return await blogDbContext.Set<TEntity>().SingleOrDefaultAsync(b => b.Id == id);
2425
}
2526

@@ -30,6 +31,7 @@ public async ValueTask<IPagedList<TEntity>> GetAllAsync(
3031
int page = 1,
3132
int pageSize = int.MaxValue)
3233
{
34+
await using var blogDbContext = await dbContextFactory.CreateDbContextAsync();
3335
var entity = blogDbContext.Set<TEntity>().AsNoTracking().AsQueryable();
3436

3537
if (filter != null)
@@ -49,6 +51,7 @@ public async ValueTask<IPagedList<TEntity>> GetAllAsync(
4951

5052
public async ValueTask StoreAsync(TEntity entity)
5153
{
54+
await using var blogDbContext = await dbContextFactory.CreateDbContextAsync();
5255
if (string.IsNullOrEmpty(entity.Id))
5356
{
5457
await blogDbContext.Set<TEntity>().AddAsync(entity);
@@ -63,6 +66,7 @@ public async ValueTask StoreAsync(TEntity entity)
6366

6467
public async ValueTask DeleteAsync(string id)
6568
{
69+
await using var blogDbContext = await dbContextFactory.CreateDbContextAsync();
6670
var entityToDelete = await GetByIdAsync(id);
6771
if (entityToDelete != null)
6872
{

tests/LinkDotNet.Blog.IntegrationTests/SqlDatabaseTestBase.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,26 @@ namespace LinkDotNet.Blog.IntegrationTests;
1212
public abstract class SqlDatabaseTestBase<TEntity> : IAsyncLifetime, IAsyncDisposable
1313
where TEntity : Entity
1414
{
15+
private readonly Mock<IDbContextFactory<BlogDbContext>> dbContextFactory;
16+
1517
protected SqlDatabaseTestBase()
1618
{
1719
var options = new DbContextOptionsBuilder()
1820
.UseSqlite(CreateInMemoryConnection())
1921
.Options;
2022
DbContext = new BlogDbContext(options);
21-
Repository = new Repository<TEntity>(new BlogDbContext(options));
23+
dbContextFactory = new Mock<IDbContextFactory<BlogDbContext>>();
24+
dbContextFactory.Setup(d => d.CreateDbContextAsync(default))
25+
.ReturnsAsync(() => new BlogDbContext(options));
26+
Repository = new Repository<TEntity>(dbContextFactory.Object);
2227
}
2328

2429
protected IRepository<TEntity> Repository { get; }
2530

2631
protected BlogDbContext DbContext { get; }
2732

33+
protected IDbContextFactory<BlogDbContext> DbContextFactory => dbContextFactory.Object;
34+
2835
public Task InitializeAsync()
2936
{
3037
return Task.CompletedTask;

tests/LinkDotNet.Blog.IntegrationTests/Web/Features/Admin/Dashboard/Components/VisitCountPerPageTests.cs

+10-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using LinkDotNet.Blog.Web.Features.Admin.Dashboard.Components;
1111
using LinkDotNet.Blog.Web.Features.Admin.Dashboard.Services;
1212
using Microsoft.AspNetCore.Components;
13+
using Microsoft.EntityFrameworkCore;
1314
using Microsoft.Extensions.DependencyInjection;
1415

1516
namespace LinkDotNet.Blog.IntegrationTests.Web.Features.Admin.Dashboard.Components;
@@ -22,8 +23,7 @@ public async Task ShouldShowCounts()
2223
var blogPost = new BlogPostBuilder().WithTitle("I was clicked").WithLikes(2).Build();
2324
await Repository.StoreAsync(blogPost);
2425
using var ctx = new TestContext();
25-
ctx.Services.AddScoped<IRepository<BlogPost>>(_ => new Repository<BlogPost>(DbContext));
26-
ctx.Services.AddScoped<IRepository<UserRecord>>(_ => new Repository<UserRecord>(DbContext));
26+
RegisterRepositories(ctx);
2727
await SaveBlogPostArticleClicked(blogPost.Id, 10);
2828

2929
var cut = ctx.RenderComponent<VisitCountPerPage>();
@@ -58,8 +58,7 @@ public async Task ShouldFilterByDate()
5858
await DbContext.SaveChangesAsync();
5959
using var ctx = new TestContext();
6060
ctx.ComponentFactories.Add<DateRangeSelector, FilterStubComponent>();
61-
ctx.Services.AddScoped<IRepository<BlogPost>>(_ => new Repository<BlogPost>(DbContext));
62-
ctx.Services.AddScoped<IRepository<UserRecord>>(_ => new Repository<UserRecord>(DbContext));
61+
RegisterRepositories(ctx);
6362
var cut = ctx.RenderComponent<VisitCountPerPage>();
6463
var filter = new Filter { StartDate = new DateTime(2019, 1, 1), EndDate = new DateTime(2020, 12, 31) };
6564

@@ -93,15 +92,20 @@ public async Task ShouldShowTotalClickCount()
9392
await DbContext.UserRecords.AddRangeAsync(new[] { clicked1, clicked2, clicked3, clicked4 });
9493
await DbContext.SaveChangesAsync();
9594
using var ctx = new TestContext();
96-
ctx.Services.AddScoped<IRepository<BlogPost>>(_ => new Repository<BlogPost>(DbContext));
97-
ctx.Services.AddScoped<IRepository<UserRecord>>(_ => new Repository<UserRecord>(DbContext));
95+
RegisterRepositories(ctx);
9896

9997
var cut = ctx.RenderComponent<VisitCountPerPage>();
10098

10199
cut.WaitForState(() => cut.FindAll("td").Any());
102100
cut.Find("#total-clicks").Unwrap().TextContent.Should().Be("4 clicks in total");
103101
}
104102

103+
private void RegisterRepositories(TestContextBase ctx)
104+
{
105+
ctx.Services.AddScoped<IRepository<BlogPost>>(_ => new Repository<BlogPost>(DbContextFactory));
106+
ctx.Services.AddScoped<IRepository<UserRecord>>(_ => new Repository<UserRecord>(DbContextFactory));
107+
}
108+
105109
private async Task SaveBlogPostArticleClicked(string blogPostId, int count)
106110
{
107111
var urlClicked = $"blogPost/{blogPostId}";

0 commit comments

Comments
 (0)