ABP Framework-对象扩展
对象扩展
当使用了实体类后发现还需要添加字段,或者只是添加临时的属性,此时可以使用IHasExtraProperties
对象扩展接口,该接口中定义了一个Dictionary属性ExtraProperties 。
ABP的使用
在ABP中,有三个类默认实现了IHasExtraProperties
接口,可通过集成这些类来进行扩展。
- 由
AggregateRoot
类实现 (参阅 entities). - 由
ExtensibleEntityDto
,ExtensibleAuditedEntityDto
... DTO基类实现. - 由
ExtensibleObject
实现, 它是一个简单的基类,任何类型的对象都可以继承.
设置/获取额外属性
除了直接使用实例.ExtraProperties来设置额外属性外,还可以通过实例.SetProperty和实例.GetProperty来使用。
SetProperty
student.SetProperty("Age", 18).SetProperty("Address", "某某小区");
student.SetProperty("Working", true);
GetProperty
var address = user.GetProperty<string>("Address");
var working = user.GetProperty<bool>("Working");
HasProperty
检查是否有这个属性
// 存在Student.Type属性
if(student.HasProperty("Student.Type")){}
RemoveProperty
删除该属性,此时HasProperty为false。
最佳实践
盲目使用扩展字段时,容易输入错误,应变为常量且不需要关注属性名称。
可以通过对于实体类的扩展来实现。
// 声明一个学生类的扩展类
public static class StudentExtensions{
// 定义一个常量作为属性名
private const string AgePrppertyName = "Student.Age";
public static void SetAge(this Student student, int age){
// 设置属性值
student.SetProperty(AgePrppertyName, age);
}
public static ing? GetAge(this Student student){
// 判断属性名是否存在
if(student.HasProperty(AgePrppertyName)){
// 返回属性名
return student.GetProperty(AgePrppertyName);
}
return null;
}
}
设置完成后可通过Student的实例调用SetAge
和GetAge
方法。
单例模式的对象扩展
在ABP中可通过ObjectExtensionManager
用于显式定义可扩展类的其他属性。可直接使用ObjectExtensionManager.Instance
去定义内部扩展对象。
AddOrUpdate
给特定的实体定义额外的属性
ObjectExtensionManager.Instance.AddOrUpdate<Student>(options=>{
options.AddOrUpdateProperty<string>("ext_param");
options.AddOrUpdateProperty<bool>("ext_is_teacher");
})
AddOrUpdateProperty
给多个实体添加同一种额外的属性
ObjectExtensionManager.Instance.AddOrUpdateProperty<string>(
new[]{typeof(StudentDto), typeof(CreateStudentDto)},
"Creater"
);
CheckPairDefinitionOnMapping
对象到对象映射
//将对象存储到对象中
var student = await _studentRepository.GetAsync(id);
student.SetProperty("teacher", "王老师");
await _studentRepository.UpdateAsync(student);
//获取该属性
var student = await _studentRepository.GetAsync(id);
return _studentRepository.GetProperty<string>("teacher");
Configuration
可通过该存储对象扩展映射到数据库的表字段中。
// Student作为实体类创建一个OrderNumber的字段,类型是int,长度为4
ObjectExtensionManager.Instance
.MapEfCoreProperty<Student, int>(
"OrderNumber",
(entityBuilder, propertyBuilder) =>
{
propertyBuilder.HasMaxLength(4);
}
);
添加完成后,需要使用EF Core的Add-Migration和Update-Database命令来创建code first迁移类并更新数据库.