Flutter中如何类型安全兼容包内BaseUser与应用User并实现注入?
问题解答
问题1:如何让应用内的User类与LoginResponse中的BaseUser实现类型兼容?
因为User是BaseUser的子类,本身具备向上兼容特性(可将User实例当作BaseUser使用)。若要将LoginResponse中的BaseUser转成User类型,有两种实用方案:
方案1:直接类型转换
如果能确定登录返回的BaseUser实例实际是User类型,可直接用类型转换:
LoginResponse response = await authenticationRepository.login(email, password); User user = response.user as User;
不确定类型时,先做检查避免报错:
if (response.user is User) { User user = response.user as User; // 处理User逻辑 } else { // 异常处理 }
方案2:给LoginResponse添加泛型支持
修改认证包中的LoginResponse为泛型类,直接指定用户类型为User:
// 认证包中修改LoginResponse class LoginResponse<T extends BaseUser> { final T user; LoginResponse({required this.user}); factory LoginResponse.fromJSON(Map<String, dynamic> json, T Function(Map<String, dynamic>) userFromJson) { return LoginResponse( user: userFromJson(json['user']), ); } }
应用层调用时传入User的解析逻辑:
// UserAPIService中的login方法 Future<LoginResponse<User>> login({required String email, required String password}) async { final response = await api.login(email, password); return LoginResponse.fromJSON(response, (userJson) => User( id: userJson['id'], email: userJson['email'], fullName: userJson['fullName'], )); }
这种方式无需后续类型转换,实现完全的类型匹配。
问题2:是否可将User类注入LoginResponse,使解析用户时调用User的命名构造函数?
完全可以,推荐两种优雅实现方式:
方式1:通过fromJSON工厂方法传入用户构造器
修改认证包的LoginResponse,让fromJSON接受一个生成用户实例的回调:
// 认证包中的LoginResponse class LoginResponse { final BaseUser user; LoginResponse({required this.user}); factory LoginResponse.fromJSON(Map<String, dynamic> json, BaseUser Function(Map<String, dynamic>) userBuilder) { // 错误处理逻辑... return LoginResponse( user: userBuilder(json['user']), ); } }
应用层定义User的命名构造函数并传入:
// User类添加命名构造函数 class User extends BaseUser { final String? fullName; User({required super.id, required super.email, this.fullName}); factory User.fromJSON(Map<String, dynamic> json) { return User( id: json['id'], email: json['email'], fullName: json['fullName'], ); } } // UserAPIService中调用 Future<LoginResponse> login({required String email, required String password}) async { final response = await api.login(email, password); return LoginResponse.fromJSON(response, User.fromJSON); }
方式2:泛型+抽象解析接口
定义抽象解析接口实现解耦,适合复杂场景:
// 认证包中定义抽象解析器 abstract class UserParser<T extends BaseUser> { T fromJSON(Map<String, dynamic> json); } // 泛型LoginResponse class LoginResponse<T extends BaseUser> { final T user; LoginResponse({required this.user}); factory LoginResponse.fromJSON(Map<String, dynamic> json, UserParser<T> parser) { return LoginResponse( user: parser.fromJSON(json['user']), ); } } // 应用层实现解析器 class UserParserImpl implements UserParser<User> { @override User fromJSON(Map<String, dynamic> json) { return User.fromJSON(json); } } // 使用时注入解析器 Future<LoginResponse<User>> login({required String email, required String password}) async { final response = await api.login(email, password); return LoginResponse.fromJSON(response, UserParserImpl()); }
内容的提问来源于stack exchange,提问作者Sudeep Bashistha
相关产品推荐
相关产品推荐

