generic IRepository
This commit is contained in:
parent
07531425f2
commit
a784630322
4
.gitignore
vendored
4
.gitignore
vendored
@ -4,10 +4,14 @@
|
|||||||
ApplicationHub/bin
|
ApplicationHub/bin
|
||||||
ApplicationHub/obj
|
ApplicationHub/obj
|
||||||
ApplicationHub/*.db
|
ApplicationHub/*.db
|
||||||
|
ApplicationHub/*.db-shm
|
||||||
|
ApplicationHub/*.db-wal
|
||||||
|
|
||||||
ApplicationHub.Data.EF/bin
|
ApplicationHub.Data.EF/bin
|
||||||
ApplicationHub.Data.EF/obj
|
ApplicationHub.Data.EF/obj
|
||||||
ApplicationHub.Data.EF/*.db
|
ApplicationHub.Data.EF/*.db
|
||||||
|
ApplicationHub.Data.EF/*.db-shm
|
||||||
|
ApplicationHub.Data.EF/*.db-wal
|
||||||
|
|
||||||
ApplicationHub.Data.InMemory/bin
|
ApplicationHub.Data.InMemory/bin
|
||||||
ApplicationHub.Data.InMemory/obj
|
ApplicationHub.Data.InMemory/obj
|
||||||
|
|||||||
@ -21,4 +21,8 @@
|
|||||||
<ProjectReference Include="..\ApplicationHub.Domain.Contracts\ApplicationHub.Domain.Contracts.csproj" />
|
<ProjectReference Include="..\ApplicationHub.Domain.Contracts\ApplicationHub.Domain.Contracts.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Authentication\ExpressionConverters\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
using ApplicationHub.Data.EF.Authentication.Entities;
|
||||||
|
using ApplicationHub.Data.EF.Utils;
|
||||||
|
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Authentication.Repositories;
|
||||||
|
|
||||||
|
public class GroupRepository(AuthenticationDataContext authenticationDataContext, IMapper mapper) : BaseRepository<Group, GroupEntity>(authenticationDataContext.Groups, mapper);
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
using ApplicationHub.Data.EF.Authentication.Entities;
|
||||||
|
using ApplicationHub.Data.EF.Utils;
|
||||||
|
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Authentication.Repositories;
|
||||||
|
|
||||||
|
public class RightRepository(AuthenticationDataContext authenticationDataContext, IMapper mapper) : BaseRepository<Right, RightEntity>(authenticationDataContext.Rights, mapper);
|
||||||
@ -1,20 +1,8 @@
|
|||||||
using ApplicationHub.Domain.Contracts.Authentication;
|
using ApplicationHub.Data.EF.Authentication.Entities;
|
||||||
|
using ApplicationHub.Data.EF.Utils;
|
||||||
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace ApplicationHub.Data.EF.Authentication.Repositories;
|
namespace ApplicationHub.Data.EF.Authentication.Repositories;
|
||||||
|
|
||||||
public class UserRepository(AuthenticationDataContext authenticationDataContext, IMapper mapper) : IUserRepository
|
public class UserRepository(AuthenticationDataContext authenticationDataContext, IMapper mapper) : BaseRepository<User, UserEntity>(authenticationDataContext.Users, mapper);
|
||||||
{
|
|
||||||
public User? GetUserByUserName(string userName)
|
|
||||||
{
|
|
||||||
return mapper.Map<List<User>>(
|
|
||||||
authenticationDataContext.Users
|
|
||||||
.Include(x => x.Groups)
|
|
||||||
.Where(x => x.UserName == userName && x.Active)
|
|
||||||
.ToList()
|
|
||||||
)
|
|
||||||
.FirstOrDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
16
ApplicationHub.Data.EF/Utils/BaseRepository.cs
Normal file
16
ApplicationHub.Data.EF/Utils/BaseRepository.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System.Linq.Expressions;
|
||||||
|
using ApplicationHub.Domain.Contracts;
|
||||||
|
using AutoMapper;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Utils;
|
||||||
|
|
||||||
|
public class BaseRepository<TModel, TEntity>(DbSet<TEntity> dbSet, IMapper mapper) : IRepository<TModel> where TEntity : class
|
||||||
|
{
|
||||||
|
public IEnumerable<TModel> Find(Expression<Func<TModel, bool>>? where = null, int? limit = null, int? offset = null, List<KeyValuePair<Expression<Func<TModel, bool>>, OrderDirection>>? order = null)
|
||||||
|
{
|
||||||
|
var resolver = new QueryResolver<TModel, TEntity>();
|
||||||
|
var result = resolver.Find(dbSet, where, limit, offset, order).ToList();
|
||||||
|
return mapper.Map<List<TModel>>(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
57
ApplicationHub.Data.EF/Utils/QueryResolver.cs
Normal file
57
ApplicationHub.Data.EF/Utils/QueryResolver.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
using System.Linq.Expressions;
|
||||||
|
using ApplicationHub.Domain.Contracts;
|
||||||
|
using ApplicationHub.Domain.Contracts.Linq;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Data.EF.Utils;
|
||||||
|
|
||||||
|
public class QueryResolver<TModel, TEntity> where TEntity : class
|
||||||
|
{
|
||||||
|
public IQueryable<TEntity> Find(DbSet<TEntity> dbSet, Expression<Func<TModel, bool>>? where = null, int? limit = null, int? offset = null, List<KeyValuePair<Expression<Func<TModel, bool>>, OrderDirection>>? order = null)
|
||||||
|
{
|
||||||
|
IQueryable<TEntity>? expression = null;
|
||||||
|
if (where != null)
|
||||||
|
{
|
||||||
|
var whereConverter = new EntityExpressionConverter<TModel, TEntity>(where.Parameters.Single());
|
||||||
|
expression = dbSet.Where(whereConverter.Convert(where));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset.HasValue)
|
||||||
|
{
|
||||||
|
expression = expression == null
|
||||||
|
? dbSet.Skip(offset.Value)
|
||||||
|
: expression.Skip(offset.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (limit.HasValue)
|
||||||
|
{
|
||||||
|
expression = expression == null
|
||||||
|
? dbSet.Take(limit.Value)
|
||||||
|
: expression.Take(limit.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (order != null && order.Any())
|
||||||
|
{
|
||||||
|
foreach (var orderDescription in order)
|
||||||
|
{
|
||||||
|
var orderConverter = new EntityExpressionConverter<TModel, TEntity>(orderDescription.Key.Parameters.Single());
|
||||||
|
var convertedOrder = orderConverter.Convert(orderDescription.Key);
|
||||||
|
switch (orderDescription.Value)
|
||||||
|
{
|
||||||
|
case OrderDirection.Asc:
|
||||||
|
expression = expression == null
|
||||||
|
? dbSet.OrderBy(convertedOrder)
|
||||||
|
: expression.OrderBy(convertedOrder);
|
||||||
|
break;
|
||||||
|
case OrderDirection.Desc:
|
||||||
|
expression = expression == null
|
||||||
|
? dbSet.OrderByDescending(convertedOrder)
|
||||||
|
: expression.OrderByDescending(convertedOrder);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return expression ?? dbSet.Where(x => true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,10 +1,11 @@
|
|||||||
using ApplicationHub.Domain.Contracts.Authentication;
|
using System.Linq.Expressions;
|
||||||
|
using ApplicationHub.Domain.Contracts;
|
||||||
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
|
|
||||||
namespace ApplicationHub.Data.InMemory.Authentication;
|
namespace ApplicationHub.Data.InMemory.Authentication;
|
||||||
|
|
||||||
public class UserDataContext(IMapper mapper) : IUserRepository
|
public class UserDataContext(IMapper mapper) : IRepository<User>
|
||||||
{
|
{
|
||||||
public User? GetUserByUserName(string userName)
|
public User? GetUserByUserName(string userName)
|
||||||
{
|
{
|
||||||
@ -13,5 +14,10 @@ public class UserDataContext(IMapper mapper) : IUserRepository
|
|||||||
.ToList();
|
.ToList();
|
||||||
return mapper.Map<List<User>>(result).FirstOrDefault();
|
return mapper.Map<List<User>>(result).FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<User> Find(Expression<Func<User, bool>>? where = null, int? limit = null, int? offset = null, List<KeyValuePair<Expression<Func<User, bool>>, OrderDirection>>? order = null)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
|
||||||
|
|
||||||
namespace ApplicationHub.Domain.Contracts.Authentication;
|
|
||||||
|
|
||||||
public interface IUserRepository
|
|
||||||
{
|
|
||||||
public User? GetUserByUserName(string userName);
|
|
||||||
}
|
|
||||||
8
ApplicationHub.Domain.Contracts/IRepository.cs
Normal file
8
ApplicationHub.Domain.Contracts/IRepository.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Domain.Contracts;
|
||||||
|
|
||||||
|
public interface IRepository<TModel>
|
||||||
|
{
|
||||||
|
IEnumerable<TModel> Find(Expression<Func<TModel, bool>>? where = null, int? limit = null, int? offset = null, List<KeyValuePair<Expression<Func<TModel, bool>>, OrderDirection>>? order = null);
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
|
namespace ApplicationHub.Domain.Contracts.Linq;
|
||||||
|
|
||||||
|
public class EntityExpressionConverter<TModel, TEntity> : ExpressionVisitor
|
||||||
|
{
|
||||||
|
private readonly ParameterExpression _entityParameter;
|
||||||
|
private readonly ParameterExpression _modelParameter;
|
||||||
|
|
||||||
|
public EntityExpressionConverter(ParameterExpression modelParameter)
|
||||||
|
{
|
||||||
|
_modelParameter = modelParameter;
|
||||||
|
_entityParameter = Expression.Parameter(typeof(TEntity), "entity");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Expression<Func<TEntity, bool>> Convert(Expression<Func<TModel, bool>> expression)
|
||||||
|
{
|
||||||
|
var body = Visit(expression.Body);
|
||||||
|
return Expression.Lambda<Func<TEntity, bool>>(body, _entityParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Expression VisitParameter(ParameterExpression node)
|
||||||
|
{
|
||||||
|
return node == _modelParameter ? _entityParameter : base.VisitParameter(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Expression VisitMember(MemberExpression node)
|
||||||
|
{
|
||||||
|
if (node.Expression == _modelParameter)
|
||||||
|
{
|
||||||
|
return Expression.Property(_entityParameter, node.Member.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.VisitMember(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
7
ApplicationHub.Domain.Contracts/OrderDirection.cs
Normal file
7
ApplicationHub.Domain.Contracts/OrderDirection.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace ApplicationHub.Domain.Contracts;
|
||||||
|
|
||||||
|
public enum OrderDirection
|
||||||
|
{
|
||||||
|
Asc,
|
||||||
|
Desc
|
||||||
|
}
|
||||||
@ -1,12 +1,12 @@
|
|||||||
using ApplicationHub.Domain.Contracts.Authentication;
|
using ApplicationHub.Domain.Contracts;
|
||||||
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
|
|
||||||
namespace Adapter.Authentication.Services;
|
namespace Adapter.Authentication.Services;
|
||||||
|
|
||||||
public class AuthenticationService(IUserRepository userRepository)
|
public class AuthenticationService(IRepository<User> userRepository)
|
||||||
{
|
{
|
||||||
public User? GetUserByUserName(string userName)
|
public User? GetUserByUserName(string userName)
|
||||||
{
|
{
|
||||||
return userRepository.GetUserByUserName(userName);
|
return userRepository.Find(x => x.UserName == userName && x.Active).FirstOrDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,8 +1,7 @@
|
|||||||
using ApplicationHub.Data.EF.Authentication.Entities;
|
using ApplicationHub.Data.EF.Authentication.Entities;
|
||||||
using ApplicationHub.Data.EF.Authentication.Repositories;
|
using ApplicationHub.Data.EF.Authentication.Repositories;
|
||||||
using ApplicationHub.Data.InMemory.Authentication;
|
using ApplicationHub.Domain.Contracts;
|
||||||
using ApplicationHub.Data.InMemory.Authentication.Entities;
|
using ApplicationHub.Domain.Contracts.Authentication.Models;
|
||||||
using ApplicationHub.Domain.Contracts.Authentication;
|
|
||||||
|
|
||||||
namespace ApplicationHub.Configuration;
|
namespace ApplicationHub.Configuration;
|
||||||
|
|
||||||
@ -16,7 +15,9 @@ public static class AdapterConfiguration
|
|||||||
{
|
{
|
||||||
// use EF implementation
|
// use EF implementation
|
||||||
builder.Services.AddAutoMapper(typeof(UserEntity));
|
builder.Services.AddAutoMapper(typeof(UserEntity));
|
||||||
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
builder.Services.AddScoped<IRepository<User>, UserRepository>();
|
||||||
|
builder.Services.AddScoped<IRepository<Group>, GroupRepository>();
|
||||||
|
builder.Services.AddScoped<IRepository<Right>, RightRepository>();
|
||||||
|
|
||||||
// use InMemory implementation
|
// use InMemory implementation
|
||||||
// builder.Services.AddScoped<IUserRepository, UserDataContext>();
|
// builder.Services.AddScoped<IUserRepository, UserDataContext>();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user