0.前言
在《asp.net core 系列》之實戰系列中,我們在之前的篇幅中對專案有了一個大概的認知,也搭建了一個基礎的專案骨架,那么就讓我們繼續完善這個骨架,讓它更加豐滿,這一篇,我將帶領小伙伴們一起實作用戶管理功能,
1. 資料表
一般情況下,我們會把用戶表和登錄資訊表放在兩個表里,為什么會這樣設計呢?出于以下幾種考慮:
- 使功能分割,用戶資訊管理是用戶管理,登錄是登錄
- 增加安全,降低無關資訊的查詢,例如訪問登錄介面不會連帶檢索用戶的普通資訊,當進行用戶資訊管理的時候,不會把登錄資訊也帶過來
等等
廢話不多說,直接上代碼:
namespace Data.Enums
{
/// <summary>
/// 登錄型別
/// </summary>
public enum LoginType : byte
{
/// token登錄
Token,
/// 用戶名密碼
Password
}
/// <summary>
/// 性別
/// </summary>
public enum SexEnum
{
/// 男
Male,
/// 女
Female,
/// 隱私
None
}
}
SysUserAuthEntity.cs
using Data.Enums;
using Data.Infrastructure;
namespace Data.Models
{
public class SysUserAuthEntity : BaseEntity<int>
{
public string UserName { get; set; }
public string Password { get; set; }
public LoginType LoginType { get; set;}
}
}
SysUserInfoEntity.cs
using System;
using Data.Enums;
using Data.Infrastructure;
namespace Data.Models
{
public class SysUserInfoEntity : BaseEntity<int>
{
public string NickName { get; set; }
public string ImageUrl { get; set; }
public SexEnum Sex { get; set; }
public DateTime? BirthDay { get; set; }
public int SysUserAuthId { get; set; }
public virtual SysUserAuthEntity SysUserAuth { get; set; }
}
}
這里并沒有使用資料庫Sql陳述句作為資料庫描述,而是使用了Entity類作為描述,這是因為資料庫到物體類之間還是有一層轉換,對于開發而言接觸更多的是物體類,而不是資料表,
2. 生成 Repository相關
使用工具代碼的方式有很多,我在這里推薦一種, Test專案中,添加一個測驗類,具體代碼如下:
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Text;
using Utils.Develop;
namespace Test
{
public class DevelopTest
{
[Test]
public void TetDevelop()
{
var d = Develop.CurrentDirect;
Console.WriteLine(d);
Assert.IsTrue(d.Contains("template"));
var entities = Develop.LoadEntities();
foreach (var item in entities)
{
Console.WriteLine(item.FullName);
}
}
[Test]
public void TestCreateDevelop()
{
var entities = Develop.LoadEntities();
foreach (var item in entities)
{
Develop.CreateRepositoryInterface(item);
Develop.CreateRepositoryImplement(item);
Develop.CreateEntityTypeConfig(item);
}
Assert.Pass();
}
}
}
具體的命令列執行比較麻煩,會執行所有的測驗單元:
cd Test/
dotnet test
當然了,IDE支持單個測驗單元的執行,具體操作這里就不做過多的介紹了,
3. Service 介面和實作類
通常Service介面會提供一個簡單Crud的Service介面,然后其他業務介面繼承該介面,這樣可以減少代碼的重復,因為重復的代碼在開發程序中是非常討厭的一種情況,因為一旦一處發生變更,其他的也有可能發生變更,所以遇到重復代碼一般都會進行一定程度的封裝:
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Data.Infrastructure;
namespace Service.Insfrastructure
{
public interface BaseService<T>
{
T Get(object key);
T Get(Expression<Func<T, bool>> predicate);
PageModel<T> SearchPage(PageCondition<T> condition);
void Delete(Expression<Func<T, bool>> predicate);
void Update(T entity);
List<T> Search(Expression<Func<T, bool>> predicate);
}
}
暫時就提供了這些最常見的請求方法,
在Service.Implements專案中:
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Data.Infrastructure;
using Domain.Insfrastructure;
using Service.Insfrastructure;
namespace Service.Implements.Insfrastructure
{
public abstract class BaseServiceImpl<T> : BaseService<T>
{
private IRepository<T> LocalRepository { get; }
protected BaseServiceImpl(IRepository<T> repository)
{
LocalRepository = repository;
}
public T Get(object key)
{
return LocalRepository.Get(key);
}
public T Get(Expression<Func<T, bool>> predicate)
{
return LocalRepository.Get(predicate);
}
public PageModel<T> SearchPage(PageCondition<T> condition)
{
return LocalRepository.Search(condition);
}
public void Delete(Expression<Func<T, bool>> predicate)
{
LocalRepository.Delete(predicate);
}
public void Update(T entity)
{
LocalRepository.Update(entity);
}
public List<T> Search(Expression<Func<T, bool>> predicate)
{
return LocalRepository.Search(predicate);
}
}
}
這個類設定為抽象類,
4. 用戶管理的介面
先創建了兩個簡單的示范介面:
using Data.Models;
using Service.Insfrastructure;
namespace Service
{
public interface ISysUserService : BaseService<SysUserInfoEntity>
{
void Register(SysUserAuthEntity auth, SysUserInfoEntity info);
void ChangePassword(int userId, string oldPwd, string newPwd);
}
}
實作類:
using System;
using Data.Models;
using Domain.Repository;
using Service.Implements.Insfrastructure;
namespace Service.Implements
{
public class SysUserServiceImpl : BaseServiceImpl<SysUserInfoEntity>, ISysUserService
{
protected ISysUserAuthRepository AuthRepository { get; }
protected ISysUserInfoRepository InfoRepository { get; }
public SysUserServiceImpl(ISysUserAuthRepository authRepository, ISysUserInfoRepository infoRepository) : base(
infoRepository)
{
AuthRepository = authRepository;
InfoRepository = infoRepository;
}
public void Register(SysUserAuthEntity auth, SysUserInfoEntity info)
{
var authItem = AuthRepository.Get(p => p.LoginType == auth.LoginType && p.UserName == auth.UserName);
if (authItem != null)
{
throw new Exception("用戶資訊已經存在");
}
info.SysUserAuth = auth;
InfoRepository.Insert(info);
}
public void ChangePassword(int userId, string oldPwd, string newPwd)
{
var info = InfoRepository.Get(userId);
var auth = AuthRepository.Get(info.SysUserAuthId);
if (oldPwd == null || oldPwd != auth?.Password)
{
throw new Exception("原密碼錯誤");
}
auth.Password = newPwd;
}
}
}
這里沒對密碼進行加密處理,直接使用明文,這在正式開發中是不允許的,密碼不能使用明文保存,當然,這也不是最終代碼,下一篇我們將介紹一下.net core中常見的加密實作,
5. 總結
這一篇通過幾個簡單的示例為大家介紹了一下Service層的開發邏輯以及理念,下一篇將為大家介紹一下.net core中幾種簡單的加密實作,
更多內容煩請關注我的博客《高先生小屋》

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/13482.html
標籤:C#
下一篇:最通俗易懂的RSA加密解密指導
