学习这个东西是这么一回事,打工这么久,有些时候是在把别人做过的东西按自己想法实现一遍。之前做上传三方报告的需求时候,其实别人已经做过上传诊断报告的需求了。
虽然两者实现的功能一样,但是代码设计上的是被秒成渣。自己做就是直接干,贫血模型一干到底,业务给domain,甚至全给application service。别人做就是充血模型,优雅。
前置笔记:领域驱动设计DDD:贫血模型和充血模型(比较重要)_董厂长的博客-优快云博客
看注释!这边实现一个具有各种刁钻需求的充血模型:
public record User
{
public int Id { get; init; }//特征一:只能初始化赋值
public DateTime CreatedDateTime { get; init; }//特征一
public string UserName { get; private set; }//特征一:只能在内部方法中改变
public int Credit { get; private set; }
private string? passwordHash;//特征三:不属于 属性 的 成员变量 映射为数据列
private string? remark;
public string? Remark //特征四:只读属性
{
get { return remark; }
}
public string? Tag { get; set; }//特征五:不想映射到数据库
private User()//特征二:给EF Core从数据库加载数据 然后生成user对象返回用的!
{
}
public User(string yhm)//特征二:给普通用户创建对象用的
{
this.UserName = yhm;
this.CreatedDateTime = DateTime.Now;
this.Credit = 10;
}
public void ChangeUserName(string newValue)
{
this.UserName = newValue;
}
public void ChangePassword(string newValue)
{
if (newValue.Length < 6)
{
throw new ArgumentException("密码太短");
}
this.passwordHash = HashHelper.Hash(newValue);
}
}
重点复习一下特征2的原理
为了完成这些特征,需要这样写配置:
class UserConfig : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
builder.Property("passwordHash");//特征三
builder.Property(u => u.Remark).HasField("remark");//特征四
builder.Ignore(u => u.Tag);//特征五
}
}
业务代码中:
User u1 = new User("FuckRJ");
u1.Tag = "MyTag";
u1.ChangePassword("123456");
ctx.Users.Add(u1);
ctx.SaveChanges();
User u1 = ctx.Users.First(u=>u.UserName=="FuckRJ");
Console.WriteLine(u1);