ABP Framework-对象扩展

发布时间 2023-07-19 18:27:56作者: 摧残一生

对象扩展

当使用了实体类后发现还需要添加字段,或者只是添加临时的属性,此时可以使用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的实例调用SetAgeGetAge方法。

单例模式的对象扩展

在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-MigrationUpdate-Database命令来创建code first迁移类并更新数据库.