Implement Repository-Service pattern
This commit is contained in:
parent
16ef307140
commit
50f20ffc5c
22 changed files with 226 additions and 110 deletions
|
@ -1,4 +1,4 @@
|
|||
using NG_2023_Kanban.BusinessLayer.Service;
|
||||
using NG_2023_Kanban.BusinessLayer.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace NG_2023_Kanban.BusinessLayer.Inject
|
||||
|
@ -8,7 +8,7 @@ namespace NG_2023_Kanban.BusinessLayer.Inject
|
|||
public static void InjectBLL(
|
||||
this IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<BusinessService>();
|
||||
services.AddScoped<UserService>();
|
||||
}
|
||||
}
|
||||
}
|
10
NG_2023_Kanban.BusinessLayer/Interfaces/IUserService.cs
Normal file
10
NG_2023_Kanban.BusinessLayer/Interfaces/IUserService.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
|
||||
namespace NG_2023_Kanban.BusinessLayer.Interfaces
|
||||
{
|
||||
public interface IUserService
|
||||
{
|
||||
Task<User> LoginAsync(User user);
|
||||
Task<User> RegisterAsync(User user);
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
using NG_2023_Kanban.DataLayer.Service;
|
||||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace NG_2023_Kanban.BusinessLayer.Service
|
||||
{
|
||||
public class BusinessService
|
||||
{
|
||||
private readonly DataService _service;
|
||||
public BusinessService(DataService service)
|
||||
{
|
||||
_service = service;
|
||||
}
|
||||
|
||||
public async Task<User> LoginAsync(string username, string password)
|
||||
{
|
||||
return await _service.LoginAsync(username, password);
|
||||
}
|
||||
|
||||
public async Task<User> RegisterAsync(string fullName, string username, string password)
|
||||
{
|
||||
User account = await _service.AddAsync(new User
|
||||
{
|
||||
FullName = fullName,
|
||||
Username = username,
|
||||
Password = password, // TODO: hashing
|
||||
IsAdmin = false
|
||||
});
|
||||
|
||||
return account;
|
||||
}
|
||||
}
|
||||
}
|
33
NG_2023_Kanban.BusinessLayer/Service/UserService.cs
Normal file
33
NG_2023_Kanban.BusinessLayer/Service/UserService.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using NG_2023_Kanban.BusinessLayer.Interfaces;
|
||||
using NG_2023_Kanban.DataLayer.Repositories;
|
||||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
using NG_2023_Kanban.DataLayer.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace NG_2023_Kanban.BusinessLayer.Services
|
||||
{
|
||||
public class UserService : IUserService
|
||||
{
|
||||
private readonly IUserRepository _userRepository;
|
||||
|
||||
public UserService(IUserRepository userRepository)
|
||||
{
|
||||
_userRepository = userRepository;
|
||||
}
|
||||
|
||||
public async Task<User?> LoginAsync(User user)
|
||||
{
|
||||
var data = await _userRepository.FindAsync(x => x.Username == user.Username && x.Password == user.Password);
|
||||
if (data.Any())
|
||||
return data.First();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<User> RegisterAsync(User user)
|
||||
{
|
||||
await _userRepository.CreateAsync(user);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,18 +6,20 @@ namespace NG_2023_Kanban.DataLayer.DbStartup
|
|||
{
|
||||
public class DatabaseContext : DbContext
|
||||
{
|
||||
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }
|
||||
public DatabaseContext(DbContextOptions options) : base(options) { }
|
||||
|
||||
public DbSet<Board> Boards { get; set; }
|
||||
public DbSet<Comment> Comments { get; set; }
|
||||
public DbSet<Card> Cards { get; set; }
|
||||
public DbSet<Column> Columns { get; set; }
|
||||
public DbSet<Comment> Comments { get; set; }
|
||||
public DbSet<User> Users { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.ApplyConfiguration(new BoardConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new CommentConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new CardConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new ColumnConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new CommentConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new UserConfiguration());
|
||||
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using NG_2023_Kanban.DataLayer.Service;
|
||||
using NG_2023_Kanban.DataLayer.Repositories;
|
||||
using NG_2023_Kanban.DataLayer.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
@ -11,12 +13,23 @@ namespace NG_2023_Kanban.DataLayer.DbStartup
|
|||
this IServiceCollection services,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
services.AddTransient<IBoardRepository, BoardRepository>();
|
||||
services.AddTransient<ICardRepository, CardRepository>();
|
||||
services.AddTransient<IColumnRepository, ColumnRepository>();
|
||||
services.AddTransient<ICommentRepository, CommentRepository>();
|
||||
services.AddTransient<IUserRepository, UserRepository>();
|
||||
|
||||
var optionsBuilder = new DbContextOptionsBuilder<DatabaseContext>();
|
||||
|
||||
optionsBuilder.UseSqlServer(configuration["ConnectionString"]);
|
||||
|
||||
services.AddDbContext<DatabaseContext>(options =>
|
||||
{
|
||||
options.UseSqlServer(
|
||||
configuration["ConnectionString"]);
|
||||
});
|
||||
services.AddScoped<DataService>();
|
||||
|
||||
(new DatabaseContext(optionsBuilder.Options)).Database.EnsureCreated(); // possibly misplaced
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
|
||||
public bool IsAdmin { get; set; }
|
||||
public bool IsAdmin { get; set; } = false;
|
||||
|
||||
public virtual ICollection<Board>? Boards { get; set; } = new HashSet<Board>();
|
||||
public virtual ICollection<Card>? Cards { get; set; } = new HashSet<Card>();
|
||||
|
|
|
@ -14,9 +14,6 @@ namespace NG_2023_Kanban.DataLayer.EntityConfiguration
|
|||
builder.Property(x => x.Name).IsRequired();
|
||||
builder.Property(x => x.Name).HasMaxLength(100);
|
||||
|
||||
builder.Property(x => x.Board).IsRequired();
|
||||
builder.Property(x => x.Board).HasMaxLength(100);
|
||||
|
||||
builder
|
||||
.HasOne(x => x.Board)
|
||||
.WithMany(x => x.Columns)
|
||||
|
|
8
NG_2023_Kanban.DataLayer/Interfaces/IBoardRepository.cs
Normal file
8
NG_2023_Kanban.DataLayer/Interfaces/IBoardRepository.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
|
||||
namespace NG_2023_Kanban.DataLayer.Interfaces
|
||||
{
|
||||
public interface IBoardRepository : IRepository<Board>
|
||||
{
|
||||
}
|
||||
}
|
8
NG_2023_Kanban.DataLayer/Interfaces/ICardRepository.cs
Normal file
8
NG_2023_Kanban.DataLayer/Interfaces/ICardRepository.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
|
||||
namespace NG_2023_Kanban.DataLayer.Interfaces
|
||||
{
|
||||
public interface ICardRepository : IRepository<Card>
|
||||
{
|
||||
}
|
||||
}
|
8
NG_2023_Kanban.DataLayer/Interfaces/IColumnRepository.cs
Normal file
8
NG_2023_Kanban.DataLayer/Interfaces/IColumnRepository.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
|
||||
namespace NG_2023_Kanban.DataLayer.Interfaces
|
||||
{
|
||||
public interface IColumnRepository : IRepository<Column>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
|
||||
namespace NG_2023_Kanban.DataLayer.Interfaces
|
||||
{
|
||||
public interface ICommentRepository : IRepository<Comment>
|
||||
{
|
||||
}
|
||||
}
|
13
NG_2023_Kanban.DataLayer/Interfaces/IRepository.cs
Normal file
13
NG_2023_Kanban.DataLayer/Interfaces/IRepository.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace NG_2023_Kanban.DataLayer.Interfaces
|
||||
{
|
||||
public interface IRepository<T> where T : class
|
||||
{
|
||||
Task<ICollection<T>> GetAllAsync();
|
||||
Task<T> GetAsync(int id);
|
||||
Task<ICollection<T>> FindAsync(Func<T, Boolean> predicate);
|
||||
Task CreateAsync(T entity);
|
||||
Task UpdateAsync(T entity);
|
||||
Task DeleteAsync(int id);
|
||||
Task DeleteAsync(T entity);
|
||||
}
|
||||
}
|
8
NG_2023_Kanban.DataLayer/Interfaces/IUserRepository.cs
Normal file
8
NG_2023_Kanban.DataLayer/Interfaces/IUserRepository.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
|
||||
namespace NG_2023_Kanban.DataLayer.Interfaces
|
||||
{
|
||||
public interface IUserRepository : IRepository<User>
|
||||
{
|
||||
}
|
||||
}
|
50
NG_2023_Kanban.DataLayer/Repositories/BaseRepository.cs
Normal file
50
NG_2023_Kanban.DataLayer/Repositories/BaseRepository.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
using NG_2023_Kanban.DataLayer.DbStartup;
|
||||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
using NG_2023_Kanban.DataLayer.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace NG_2023_Kanban.DataLayer.Repositories;
|
||||
|
||||
public class BaseRepository<T> : IRepository<T> where T : BaseEntity
|
||||
{
|
||||
private DatabaseContext _context;
|
||||
|
||||
public BaseRepository(DatabaseContext context)
|
||||
=> _context = context;
|
||||
|
||||
public async Task<ICollection<T>> GetAllAsync()
|
||||
=> await _context.Set<T>().Select(x => x).ToListAsync();
|
||||
|
||||
public async Task<T> GetAsync(int id)
|
||||
=> await _context.Set<T>().FirstAsync(x => x.Id == id);
|
||||
|
||||
public async Task<ICollection<T>> FindAsync(Func<T, bool> predicate)
|
||||
{
|
||||
var entities = await GetAllAsync();
|
||||
return entities.Where(predicate).ToList();
|
||||
}
|
||||
|
||||
public async Task CreateAsync(T entity)
|
||||
{
|
||||
await _context.Set<T>().AddAsync(entity);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task UpdateAsync(T entity)
|
||||
{
|
||||
_context.Set<T>().Update(entity);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(int id)
|
||||
{
|
||||
var entity = await GetAsync(id);
|
||||
await DeleteAsync(entity);
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(T entity)
|
||||
{
|
||||
_context.Set<T>().Remove(entity);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
10
NG_2023_Kanban.DataLayer/Repositories/BoardRepository.cs
Normal file
10
NG_2023_Kanban.DataLayer/Repositories/BoardRepository.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using NG_2023_Kanban.DataLayer.DbStartup;
|
||||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
using NG_2023_Kanban.DataLayer.Interfaces;
|
||||
|
||||
namespace NG_2023_Kanban.DataLayer.Repositories;
|
||||
|
||||
public class BoardRepository : BaseRepository<Board>, IBoardRepository
|
||||
{
|
||||
public BoardRepository(DatabaseContext context) : base(context) { }
|
||||
}
|
10
NG_2023_Kanban.DataLayer/Repositories/CardRepository.cs
Normal file
10
NG_2023_Kanban.DataLayer/Repositories/CardRepository.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using NG_2023_Kanban.DataLayer.DbStartup;
|
||||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
using NG_2023_Kanban.DataLayer.Interfaces;
|
||||
|
||||
namespace NG_2023_Kanban.DataLayer.Repositories;
|
||||
|
||||
public class CardRepository : BaseRepository<Card>, ICardRepository
|
||||
{
|
||||
public CardRepository(DatabaseContext context) : base(context) { }
|
||||
}
|
10
NG_2023_Kanban.DataLayer/Repositories/ColumnRepository.cs
Normal file
10
NG_2023_Kanban.DataLayer/Repositories/ColumnRepository.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using NG_2023_Kanban.DataLayer.DbStartup;
|
||||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
using NG_2023_Kanban.DataLayer.Interfaces;
|
||||
|
||||
namespace NG_2023_Kanban.DataLayer.Repositories;
|
||||
|
||||
public class ColumnRepository : BaseRepository<Column>, IColumnRepository
|
||||
{
|
||||
public ColumnRepository(DatabaseContext context) : base(context) { }
|
||||
}
|
10
NG_2023_Kanban.DataLayer/Repositories/CommentRepository.cs
Normal file
10
NG_2023_Kanban.DataLayer/Repositories/CommentRepository.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using NG_2023_Kanban.DataLayer.DbStartup;
|
||||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
using NG_2023_Kanban.DataLayer.Interfaces;
|
||||
|
||||
namespace NG_2023_Kanban.DataLayer.Repositories;
|
||||
|
||||
public class CommentRepository : BaseRepository<Comment>, ICommentRepository
|
||||
{
|
||||
public CommentRepository(DatabaseContext context) : base(context) { }
|
||||
}
|
10
NG_2023_Kanban.DataLayer/Repositories/UserRepository.cs
Normal file
10
NG_2023_Kanban.DataLayer/Repositories/UserRepository.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using NG_2023_Kanban.DataLayer.DbStartup;
|
||||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
using NG_2023_Kanban.DataLayer.Interfaces;
|
||||
|
||||
namespace NG_2023_Kanban.DataLayer.Repositories;
|
||||
|
||||
public class UserRepository : BaseRepository<User>, IUserRepository
|
||||
{
|
||||
public UserRepository(DatabaseContext context) : base(context) { }
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
using NG_2023_Kanban.DataLayer.DbStartup;
|
||||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace NG_2023_Kanban.DataLayer.Service
|
||||
{
|
||||
public class DataService
|
||||
{
|
||||
private readonly DatabaseContext _context;
|
||||
public DataService(DatabaseContext context)
|
||||
{
|
||||
_context = context;
|
||||
_context.Database.EnsureCreated();
|
||||
}
|
||||
|
||||
public async Task<User> AddAsync(User entity)
|
||||
{
|
||||
await _context.Set<User>().AddAsync(entity);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public async Task<User> GetByIdAsync(int id)
|
||||
{
|
||||
var entity = await _context.Set<User>().FirstOrDefaultAsync(x => x.Id == id);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public async Task<User> LoginAsync(string username, string password)
|
||||
{
|
||||
User? entity = await _context.Set<User>().FirstOrDefaultAsync(x => x.Username == username);
|
||||
|
||||
if (entity != null && entity.Password == password) // TODO: hashing
|
||||
return entity;
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<ICollection<User>> GetAllAsync()
|
||||
{
|
||||
var entities = await _context.Set<User>().Select(x => x).ToListAsync();
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
public async Task UpdateAsync(User model)
|
||||
{
|
||||
_context.Set<User>().Update(model);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(User model)
|
||||
{
|
||||
_context.Set<User>().Remove(model);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,19 +3,19 @@ using Microsoft.AspNetCore.Mvc;
|
|||
using NG_2023_Kanban.DataLayer.Entities;
|
||||
using NG_2023_Kanban.Extensions;
|
||||
using NG_2023_Kanban.DataLayer.Models;
|
||||
using NG_2023_Kanban.BusinessLayer.Service;
|
||||
using NG_2023_Kanban.BusinessLayer.Services;
|
||||
|
||||
namespace NG_2023_Kanban.Controllers;
|
||||
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private readonly BusinessService _service;
|
||||
private readonly UserService _userService;
|
||||
private readonly ILogger<HomeController> _logger;
|
||||
|
||||
public HomeController(ILogger<HomeController> logger, BusinessService service)
|
||||
public HomeController(ILogger<HomeController> logger, UserService userService)
|
||||
{
|
||||
_logger = logger;
|
||||
_service = service;
|
||||
_userService = userService;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
|
@ -39,13 +39,13 @@ public class HomeController : Controller
|
|||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Login(string username, string password)
|
||||
public async Task<IActionResult> Login(User user)
|
||||
{
|
||||
User? currentAccount = HttpContext.Session.GetObject<User>("Account");
|
||||
if (currentAccount != null)
|
||||
return Redirect("/Home/Index");
|
||||
|
||||
User? account = await _service.LoginAsync(username, password);
|
||||
User? account = await _userService.LoginAsync(user);
|
||||
if (account != null)
|
||||
{
|
||||
HttpContext.Session.SetObject("Account", account);
|
||||
|
@ -74,7 +74,7 @@ public class HomeController : Controller
|
|||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Register(string fullName, string username, string password)
|
||||
public async Task<IActionResult> Register(User user)
|
||||
{
|
||||
User? currentAccount = HttpContext.Session.GetObject<User>("Account");
|
||||
if (currentAccount != null)
|
||||
|
@ -82,7 +82,7 @@ public class HomeController : Controller
|
|||
|
||||
try
|
||||
{
|
||||
User account = await _service.RegisterAsync(fullName, username, password);
|
||||
User account = await _userService.RegisterAsync(user);
|
||||
|
||||
HttpContext.Session.SetObject("Account", account);
|
||||
return Redirect("/Home/Index");
|
||||
|
|
Reference in a new issue