using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading.Tasks;
using Timeline.Entities;
using Timeline.Models;
namespace Timeline.Services
{
public interface IUserDetailService
{
///
/// Get the nickname of user.
///
/// The username to get nickname of.
/// The user's nickname. Null if not set.
/// Thrown if is null or empty.
/// Thrown if user doesn't exist.
Task GetUserNickname(string username);
///
/// Get the detail of user.
///
/// The username to get user detail of.
/// The user detail.
/// Thrown if is null or empty.
/// Thrown if user doesn't exist.
Task GetUserDetail(string username);
///
/// Update the detail of user. This function does not do data check.
///
/// The username to get user detail of.
/// The detail to update. Can't be null. Any null member means not set.
/// Thrown if is null or empty or is null.
/// Thrown if user doesn't exist.
Task UpdateUserDetail(string username, UserDetail detail);
}
public class UserDetailService : IUserDetailService
{
private readonly ILogger _logger;
private readonly DatabaseContext _databaseContext;
public UserDetailService(ILogger logger, DatabaseContext databaseContext)
{
_logger = logger;
_databaseContext = databaseContext;
}
private async Task CreateEntity(long userId)
{
var entity = new UserDetailEntity()
{
UserId = userId
};
_databaseContext.UserDetails.Add(entity);
await _databaseContext.SaveChangesAsync();
_logger.LogInformation("An entity is created in user_details.");
return entity;
}
// Check the existence of user detail entry
private async Task CheckAndInit(long userId)
{
var detail = await _databaseContext.UserDetails.Where(e => e.UserId == userId).SingleOrDefaultAsync();
if (detail == null)
{
detail = await CreateEntity(userId);
}
return detail;
}
public async Task GetUserNickname(string username)
{
var userId = await DatabaseExtensions.CheckAndGetUser(_databaseContext.Users, username);
var detail = await _databaseContext.UserDetails.Where(e => e.UserId == userId).Select(e => new { e.Nickname }).SingleOrDefaultAsync();
if (detail == null)
{
var entity = await CreateEntity(userId);
return null;
}
else
{
var nickname = detail.Nickname;
return string.IsNullOrEmpty(nickname) ? null : nickname;
}
}
public async Task GetUserDetail(string username)
{
var userId = await DatabaseExtensions.CheckAndGetUser(_databaseContext.Users, username);
var detailEntity = await CheckAndInit(userId);
return UserDetail.From(detailEntity);
}
public async Task UpdateUserDetail(string username, UserDetail detail)
{
if (detail == null)
throw new ArgumentNullException(nameof(detail));
var userId = await DatabaseExtensions.CheckAndGetUser(_databaseContext.Users, username);
var detailEntity = await CheckAndInit(userId);
if (detail.Nickname != null)
detailEntity.Nickname = detail.Nickname;
if (detail.QQ != null)
detailEntity.QQ = detail.QQ;
if (detail.Email != null)
detailEntity.Email = detail.Email;
if (detail.PhoneNumber != null)
detailEntity.PhoneNumber = detail.PhoneNumber;
if (detail.Description != null)
detailEntity.Description = detail.Description;
await _databaseContext.SaveChangesAsync();
_logger.LogInformation("An entity is updated in user_details.");
}
}
public static class UserDetailServiceCollectionExtensions
{
public static void AddUserDetailService(this IServiceCollection services)
{
services.AddScoped();
}
}
}