Skip to content

Commit a4ace4f

Browse files
committed
#22 add more stuffs for mongo provider
1 parent 7d73bd2 commit a4ace4f

File tree

13 files changed

+341
-213
lines changed

13 files changed

+341
-213
lines changed

samples/BiMonetaryApi/Controllers/TickerController.cs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Threading.Tasks;
45
using Microsoft.AspNetCore.Mvc;
56
using NetCoreKit.Domain;
7+
using NetCoreKit.Infrastructure.Mongo;
68

79
namespace NetCoreKit.Samples.BiMonetaryApi.Controllers
810
{
@@ -13,13 +15,13 @@ public class Ticker : AggregateRootBase
1315
public int Rank { get; set; }
1416
public double PriceUsd { get; private set; }
1517
public double PriceBtc { get; private set; }
16-
public double Volumn24HUsd { get; private set; }
18+
public double Volumn24hUsd { get; private set; }
1719
public double MarketCapUsd { get; private set; }
1820
public double AvailableSupply { get; private set; }
1921
public double TotalSupply { get; private set; }
20-
public string PercentChange1H { get; private set; }
21-
public string PercentChange24H { get; private set; }
22-
public string PercentChange7D { get; private set; }
22+
public string PercentChange1h { get; private set; }
23+
public string PercentChange24h { get; private set; }
24+
public string PercentChange7d { get; private set; }
2325
public DateTime LastSyncWithService { get; private set; }
2426
public string Link { get; private set; }
2527
}
@@ -39,19 +41,28 @@ public TickerController(IQueryRepositoryFactory repositoryFactory, IUnitOfWorkAs
3941

4042
// GET api/tickers
4143
[HttpGet]
42-
public ActionResult<IEnumerable<Ticker>> Get()
44+
public async Task<ActionResult<PaginatedItem<Ticker>>> Get([FromQuery] Criterion criterion)
4345
{
44-
var repo = _repositoryFactory.QueryRepository<Ticker>();
45-
var tickers = repo.Queryable().ToList();
46+
var repo = _repositoryFactory.MongoQueryRepository<Ticker>();
47+
var tickers = await repo.QueryAsync(criterion, ticker => ticker);
4648
return tickers;
4749
}
4850

4951
// GET api/tickers/{C35A5A15-0913-43A0-BAD5-00FE9749C320}
5052
[HttpGet("{id:guid}")]
51-
public ActionResult<Ticker> Get(Guid id)
53+
public async Task<ActionResult<Ticker>> Get(Guid id)
5254
{
53-
var repo = _repositoryFactory.QueryRepository<Ticker>();
54-
var ticker = repo.Queryable().FirstOrDefault(x => x.Id == id);
55+
var repo = _repositoryFactory.MongoQueryRepository<Ticker>();
56+
var ticker = await repo.FindOneAsync(x => x.Id, id);
57+
return ticker;
58+
}
59+
60+
// GET api/tickers/name/ETH
61+
[HttpGet("{name}")]
62+
public async Task<ActionResult<Ticker>> GetByName(string name)
63+
{
64+
var repo = _repositoryFactory.MongoQueryRepository<Ticker>();
65+
var ticker = await repo.FindOneAsync(x => x.Name, name);
5566
return ticker;
5667
}
5768

src/NetCoreKit.Domain/Criterion.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ public class Criterion
66
{
77
private const int MaxPageSize = 50;
88
private const int ConfigurablePageSize = 10;
9+
private const string DefaultSortBy = "Id";
10+
private const string DefaultSortOrder = "desc";
911

1012
public Criterion()
1113
{
12-
CurrentPage = 0;
14+
CurrentPage = 1;
1315
PageSize = ConfigurablePageSize;
14-
SortBy = "Id";
15-
SortOrder = "desc";
1616
}
1717

1818
public int CurrentPage { get; set; }
@@ -21,12 +21,22 @@ public Criterion()
2121
public int PageSize
2222
{
2323
get => _pageSize;
24-
set => _pageSize = (value > MaxPageSize) ? MaxPageSize :
25-
(value < ConfigurablePageSize ? ConfigurablePageSize : value);
24+
set => _pageSize = (value > MaxPageSize) ? MaxPageSize : (value < 1 ? 1 : value);
2625
}
2726

28-
public string SortBy { get; private set; }
29-
public string SortOrder { get; private set; }
27+
private string _sortBy = DefaultSortBy;
28+
public string SortBy
29+
{
30+
get => _sortBy;
31+
set => _sortBy = string.IsNullOrEmpty(value) ? DefaultSortBy : value;
32+
}
33+
34+
private string _sortOrder = DefaultSortOrder;
35+
public string SortOrder
36+
{
37+
get => _sortOrder;
38+
set => _sortOrder = string.IsNullOrEmpty(value) ? DefaultSortOrder : value;
39+
}
3040

3141
public Criterion SetPageSize(int pageSize)
3242
{

src/NetCoreKit.Domain/PaginatedItem.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ namespace NetCoreKit.Domain
44
{
55
public class PaginatedItem<TResponse> : ValueObjectBase
66
{
7-
public PaginatedItem(int totalItems, int totalPages, IReadOnlyList<TResponse> items)
7+
public PaginatedItem(long totalItems, long totalPages, IReadOnlyList<TResponse> items)
88
{
99
TotalItems = totalItems;
1010
TotalPages = totalPages;
1111
Items = items;
1212
}
1313

14-
public int TotalItems { get; }
14+
public long TotalItems { get; }
1515

1616
public long TotalPages { get; }
1717

src/NetCoreKit.Infrastructure.EfCore/Extensions/OrderByExtension.cs

Lines changed: 0 additions & 45 deletions
This file was deleted.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using NetCoreKit.Domain;
2+
3+
namespace NetCoreKit.Infrastructure.Mongo
4+
{
5+
public interface IMongoQueryRepository<out TEntity> : IQueryRepository<TEntity>
6+
where TEntity : IAggregateRoot
7+
{
8+
MongoContext DbContext { get; }
9+
}
10+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
using System;
2+
using System.Linq.Expressions;
3+
using System.Threading.Tasks;
4+
using MongoDB.Driver;
5+
using NetCoreKit.Domain;
6+
7+
namespace NetCoreKit.Infrastructure.Mongo
8+
{
9+
public static class MongoQueryRepositoryExtensions
10+
{
11+
public static async Task<TEntity> FindOneAsync<TEntity, TId>(
12+
this IMongoQueryRepository<TEntity> repo,
13+
Expression<Func<TEntity, TId>> filter,
14+
TId id)
15+
where TEntity : class, IAggregateRoot
16+
{
17+
var collection = repo.DbContext.Collection<TEntity>();
18+
var filterDef = Builders<TEntity>.Filter.Eq(filter, id);
19+
return await collection.Find(filterDef).FirstOrDefaultAsync();
20+
}
21+
22+
public static async Task<PaginatedItem<TResponse>> QueryAsync<TEntity, TResponse>(
23+
this IMongoQueryRepository<TEntity> repo,
24+
Criterion criterion,
25+
Expression<Func<TEntity, TResponse>> selector)
26+
where TEntity : class, IAggregateRoot
27+
{
28+
return await GetDataAsync(repo, criterion, selector);
29+
}
30+
31+
public static async Task<PaginatedItem<TResponse>> FindAllAsync<TEntity, TResponse>(
32+
this IMongoQueryRepository<TEntity> repo,
33+
Criterion criterion,
34+
Expression<Func<TEntity, TResponse>> selector,
35+
Expression<Func<TEntity, bool>> filter)
36+
where TEntity : class, IAggregateRoot
37+
{
38+
return await GetDataAsync(repo, criterion, selector, filter);
39+
}
40+
41+
private static async Task<PaginatedItem<TResponse>> GetDataAsync<TEntity, TResponse>(
42+
IMongoQueryRepository<TEntity> repo,
43+
Criterion criterion,
44+
Expression<Func<TEntity, TResponse>> selector,
45+
Expression<Func<TEntity, bool>> filter = null)
46+
where TEntity : class, IAggregateRoot
47+
{
48+
var collection = repo.DbContext.Collection<TEntity>();
49+
FilterDefinition<TEntity> filterDef = null;
50+
SortDefinition<TEntity> sortDef = null;
51+
52+
if (filter != null)
53+
filterDef = Builders<TEntity>.Filter.Eq(filter, true);
54+
55+
if (!string.IsNullOrWhiteSpace(criterion.SortBy))
56+
{
57+
var isDesc = string.Equals(criterion.SortOrder, "desc", StringComparison.OrdinalIgnoreCase);
58+
FieldDefinition<TEntity> field = criterion.SortBy;
59+
sortDef = !isDesc
60+
? Builders<TEntity>.Sort.Ascending(field)
61+
: Builders<TEntity>.Sort.Descending(field);
62+
}
63+
64+
// default we will set it at 0-index
65+
if (criterion.CurrentPage > 0) criterion.CurrentPage--;
66+
67+
var results = await collection
68+
.FindEntityWithProjection(filterDef, selector)
69+
.SortEntity(sortDef)
70+
.Skip(criterion.CurrentPage * criterion.PageSize)
71+
.Limit(criterion.PageSize)
72+
.ToListAsync();
73+
74+
var totalRecord = await collection.CountDocumentsAsync(FilterDefinition<TEntity>.Empty);
75+
var totalPages = (int)Math.Ceiling((double)totalRecord / criterion.PageSize);
76+
77+
if (criterion.CurrentPage > totalPages)
78+
{
79+
// criterion.SetCurrentPage(totalPages);
80+
}
81+
82+
return new PaginatedItem<TResponse>(totalRecord, totalPages, results);
83+
}
84+
85+
private static IFindFluent<TEntity, TResponse> SortEntity<TEntity, TResponse>(this IFindFluent<TEntity, TResponse> collectionFluent,
86+
SortDefinition<TEntity> sortDef
87+
) where TEntity : class, IAggregateRoot
88+
{
89+
return collectionFluent.Sort(sortDef);
90+
}
91+
92+
private static IFindFluent<TEntity, TResponse> FindEntityWithProjection<TEntity, TResponse>(this IMongoCollection<TEntity> collection,
93+
FilterDefinition<TEntity> filterDef,
94+
Expression<Func<TEntity, TResponse>> selector
95+
) where TEntity : class, IAggregateRoot
96+
{
97+
return filterDef != null
98+
? collection.Find(filterDef).Project(selector)
99+
: collection.Find(FilterDefinition<TEntity>.Empty).Project(selector);
100+
}
101+
}
102+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
using NetCoreKit.Domain;
3+
4+
namespace NetCoreKit.Infrastructure.Mongo
5+
{
6+
public class MongoQueryRepositoryFactory : IQueryRepositoryFactory
7+
{
8+
private readonly IServiceProvider _serviceProvider;
9+
10+
public MongoQueryRepositoryFactory(IServiceProvider serviceProvider)
11+
{
12+
_serviceProvider = serviceProvider;
13+
}
14+
15+
public IQueryRepository<TEntity> QueryRepository<TEntity>() where TEntity : IAggregateRoot
16+
{
17+
return _serviceProvider.GetService(typeof(IQueryRepository<TEntity>)) as IQueryRepository<TEntity>;
18+
}
19+
}
20+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using NetCoreKit.Domain;
2+
3+
namespace NetCoreKit.Infrastructure.Mongo
4+
{
5+
public static class MongoQueryRepositoryFactoryExtensions
6+
{
7+
public static IMongoQueryRepository<TEntity> MongoQueryRepository<TEntity>(this IQueryRepositoryFactory factory)
8+
where TEntity : IAggregateRoot
9+
{
10+
return factory.QueryRepository<TEntity>() as IMongoQueryRepository<TEntity>;
11+
}
12+
}
13+
}

0 commit comments

Comments
 (0)