You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Clean架构下使用Isar Generator遇参数与属性类型不匹配错误

Isar Generator 报错:构造函数参数类型与属性类型不匹配

我在项目中采用Clean架构,想给应用添加数据库,选择了Isar数据库。按照Clean架构要求,只在Model层而非Entity层创建Isar集合,但给Model创建集合并用Isar Generator生成代码时,一直报错。

错误信息

[INFO] Generating build script completed, took 875ms
[INFO] Reading cached asset graph completed, took 231ms
[INFO] Checking for updates since last build completed, took 3.3s
[SEVERE] isar_generator on lib/data/models/plugin.dart:

Constructor parameter type does not match property type
package:meiyou/data/models/plugin.dart:24:11
╷
24 │ super.dependencies,
│ ^^^^^^^^^^^^
╵
[INFO] Running build completed, took 5.2s
[INFO] Caching finalized dependency graph completed, took 181ms
[SEVERE] Failed after 5.4s

相关代码

import 'dart:convert';
import 'package:meiyou/core/utils/extenstions/iterable.dart';
import 'package:meiyou/core/utils/from_entity.dart';
import 'package:meiyou/domain/entities/plugin.dart';
import 'package:isar/isar.dart';
part 'plugin.g.dart';

@collection
class Plugin extends PluginEntity {
  final Id id;

  @override
  List<Dependency>? get dependencies =>
      super.dependencies?.mapAsList<Dependency>(
          (it) => it is Dependency ? it : Dependency.fromEntity(it));

  const Plugin({
    this.id = Isar.autoIncrement,
    required super.name,
    required super.source,
    required super.version,
    super.icon,
    super.info,
    super.dependencies,
  });

  factory Plugin.fromEntity(PluginEntity entity) {
    return createFromEntity<PluginEntity, Plugin>(
        entity,
        Plugin(
          name: entity.name,
          source: entity.source,
          version: entity.version,
          icon: entity.icon,
          info: entity.info,
          dependencies: entity.dependencies?.mapAsList<Dependency>(
              (it) => it is Dependency ? it : Dependency.fromEntity(it)),
        ));
  }

  factory Plugin.decode(String jsonString) =>
      Plugin.fromJson(jsonDecode(jsonString));

  factory Plugin.fromJson(dynamic json) {
    return Plugin(
      name: json['name'],
      source: json['source'],
      version: json['version'],
      icon: json['icon'],
      info: json['info'],
      dependencies: (json['dependencies'] as List?)
          ?.mapAsList((it) => Dependency.fromJson(it)),
    );
  }

  String get encode => jsonEncode(toJson());

  Map<String, dynamic> toJson() {
    return {
      "name": name,
      "source": source,
      "version": version,
      "icon": icon,
      "info": info,
      "dependencies": dependencies?.mapAsList((e) => e.toJson()),
    };
  }

  Plugin copyWith({
    String? name,
    String? source,
    String? version,
    String? icon,
    String? info,
    List<Dependency>? dependencies,
  }) {
    return Plugin(
      name: name ?? this.name,
      source: source ?? this.source,
      version: version ?? this.version,
      icon: icon ?? this.icon,
      info: info ?? this.info,
      dependencies: dependencies ?? this.dependencies,
    );
  }

  @override
  String toString() {
    return '''Plugin(name: $name, source: $source, version: $version, icon: $icon, info: $info, dependencies: $dependencies)''';
  }
}

@embedded
class Dependency extends DependencyEntity {
  final Id id;
  const Dependency({
    this.id = Isar.autoIncrement,
    required super.name,
    required super.source,
    required super.version,
  });

  factory Dependency.fromEntity(DependencyEntity entity) {
    return Dependency(
      name: entity.name,
      source: entity.source,
      version: entity.version,
    );
  }

  factory Dependency.decode(String jsonString) =>
      Dependency.fromJson(jsonDecode(jsonString));

  factory Dependency.fromJson(dynamic json) {
    return Dependency(
      name: json['name'],
      source: json['source'],
      version: json['version'],
    );
  }

  String get encode => jsonEncode(toJson());
  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'source': source,
      'version': version,
    };
  }

  @override
  String toString() {
    return '''Dependency(name: $name, source: $source, version: $version)''';
  }
}

问题原因

报错核心是:你在Plugin类中重写了dependencies属性,将父类PluginEntity的List<DependencyEntity>?类型转换成了List<Dependency>?类型,但构造函数直接传递super.dependencies时,Isar Generator无法识别这种类型不匹配——它要求构造参数类型和类中属性类型完全一致。

解决办法

方案一:重新定义Model层的dependencies属性

去掉@override,自己定义Isar可识别的dependencies属性,同时在构造函数中处理父类的依赖赋值:

@collection
class Plugin extends PluginEntity {
  final Id id;
  final List<Dependency>? dependencies;

  const Plugin({
    this.id = Isar.autoIncrement,
    required super.name,
    required super.source,
    required super.version,
    super.icon,
    super.info,
    List<Dependency>? dependencies,
  }) : dependencies = dependencies,
       super(dependencies: dependencies?.map((d) => d as DependencyEntity).toList());

  // 其他代码保持不变
}

方案二:给重写的属性添加@ignore注解

如果坚持重写父类属性,可通过@ignore让Isar忽略该属性,同时定义一个Isar可存储的属性:

@collection
class Plugin extends PluginEntity {
  final Id id;

  @ignore
  @override
  List<Dependency>? get dependencies =>
      super.dependencies?.mapAsList<Dependency>(
          (it) => it is Dependency ? it : Dependency.fromEntity(it));

  final List<Dependency>? _storedDependencies;

  const Plugin({
    this.id = Isar.autoIncrement,
    required super.name,
    required super.source,
    required super.version,
    super.icon,
    super.info,
    List<Dependency>? dependencies,
  }) : _storedDependencies = dependencies,
       super(dependencies: dependencies?.map((d) => d as DependencyEntity).toList());

  // 其他代码保持不变
}

额外说明

Clean架构下Model层继承Entity层是合理的,但Isar对实体类类型要求严格,所有需存储的属性必须是Isar支持的类型,且构造参数与属性类型要完全匹配。优先推荐方案一,既符合Clean架构分层要求,又能满足Isar生成规则。

内容的提问来源于stack exchange,提问作者Omega500

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:54:52