패키지, 저장소 및 앱 카테고리 검색

패키지 상세v8.13.0

built_value_generator

빌더를 갖춘 값 유형, 열거형으로 사용하는 Dart 클래스 및 직렬화. 이 라이브러리는 개발용 종속성입니다.

AndroidiOSmacOSWindowsLinux
30일 다운로드
41.8만
좋아요
148
Pub 점수
160

패키지 설치

flutter pub add built_value_generator

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

Built Value Generator는 Dart용 코드 생성 도구로, 내장 빌더, 열거형과 유사한 동작 및 원활한 JSON 직렬화를 갖춘 불변 값 클래스를 생성할 수 있게 해줍니다. 생성자, getter, 직렬화 메서드에 대한 반복 코드를 자동으로 생성하여 오류를 줄이고 코드 유지보수성을 향상시킵니다. 개발용 종속성으로 설계되어 built_value와 함께 사용해 Flutter 및 Dart 애플리케이션에서 데이터 모델링을 간소화합니다. 이 생성기는 Android, iOS, macOS, Windows, Linux 등 여러 플랫폼을 지원합니다.

사용 사례

  • 불변 데이터 모델링
  • JSON 직렬화
  • 타입 안전한 구성 객체
  • 앱에서의 상태 관리
  • 복잡한 데이터 구조에 대한 코드 생성

주요 기능

  • 자동 빌더 패턴 생성
  • 열거형과 유사한 클래스 동작
  • 내장된 JSON 직렬화
  • 최소한의 보일러플레이트
  • 널 안전성 지원

적합한 대상

  • 불변 데이터가 필요한 Flutter 앱
  • API 기반 애플리케이션
  • 대규모 상태 관리
  • 타입 안전성을 우선시하는 팀
  • 코드 생성을 사용하는 프로젝트

고려 사항

  • build_runner 설정이 필요합니다
  • 빌드 시 종속성 추가
  • 제한된 런타임 사용자 정의
  • 동적 데이터에 적합하지 않음
  • 가변 클래스에서의 주의 깊은 마이그레이션 필요

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

Build

Built Values for Dart - Introduction

Built Value provides:

  • Immutable value types;
  • EnumClass, classes that behave like enums;
  • JSON serialization.

Immutable collections are from built_collection.

See the API docs.

Articles

Tutorials

Tools

Examples

For an end to end example see the chat example, which was demoed at the Dart Summit 2016. The data model, used both client and server side, uses value types, enums and serialization from built_value.

Simple examples are here.

Codegen

Codegen is done using dart run build_runner build for one-off builds.

To continuously watch your source and update the generated output when it changes, use dart run build_runner watch.

Note that you need a dev dependency on built_value_generator and build_runner. See the example pubspec.yaml.

Value Types

Value types are, for our purposes, classes that are considered interchangeable if their fields have the same values.

Common examples include Date, Money and Url. Most code introduces its own value types. For example, every web app probably has some version of Account and User.

Value types are very commonly sent by RPC and/or stored for later retrieval.

The problems that led to the creation of the Built Value library have been discussed at great length in the context of AutoValue for Java.

In short: creating and maintaining value types by hand requires a lot of boilerplate. It's boring to write, and if you make a mistake, you very likely create a bug that's hard to track down.

Any solution for value types needs to allow them to participate in object oriented design. Date, for example, is the right place for code that does simple date manipulation.

AutoValue solves the problem for Java with code generation, and Built Values does the same for Dart. The boilerplate is generated for you, leaving you to specify which fields you need and to add code for the behaviour of the class.

Generating boilerplate for Value Types

Value types require a bit of boilerplate in order to connect it to generated code. Luckily, even this bit of boilerplate can be automated using code snippets support in your favourite text editor. For example, in IntelliJ you can use the following live template:

abstract class $CLASS_NAME$ implements Built<$CLASS_NAME$, $CLASS_NAME$Builder> {
  $CLASS_NAME$._();
  factory $CLASS_NAME$([void Function($CLASS_NAME$Builder) updates]) = _$$$CLASS_NAME$;
}

Using this template, you would only have to manually enter a name for your data class, which is something that can't be automated.

Enum Class

Enum Classes provide classes with enum features.

Enums are very helpful in modelling the real world: whenever there are a small fixed set of options, an enum is a natural choice. For an object oriented design, though, enums need to be classes. Dart falls short here, so Enum Classes provide what's missing!

Design:

  • Constants have name and toString, can be used in switch statements, and are real classes that can hold code and implement interfaces
  • Generated values method that returns all the enum values in a BuiltSet (immutable set)
  • Generated valueOf method that takes a String

Serialization

Built Values comes with JSON serialization support which allows you to serialize a complete data model of Built Values, Enum Classes and Built Collections. The chat example shows how easy this makes building a full application with Dart on the server and client.

Here are the major features of the serialization support:

It fully supports object oriented design: any object model that you can design can be serialized, including full use of generics and interfaces. Some other libraries require concrete types or do not fully support generics.

It allows different object oriented models over the same data. For example, in a client server application, it's likely that the client and server want different functionality from their data model. So, they are allowed to have different classes that map to the same data. Most other libraries enforce a 1:1 mapping between classes and types on the wire.

It requires well behaved types. They must be immutable, can use interface but not concrete inheritance, must have predictable nullability, hashCode, equals and toString. In fact, they must be Enum Classes, Built Collections or Built Values. Some other libraries allow badly behaved types to be serialized.

It supports changes to the data model. Optional fields can be added or removed, and fields can be switched from optional to required, allowing your data model to evolve without breaking compatbility. Some other libraries break compatibility on any change to any serializable class.

It's modular. Each endpoint can choose which classes to know about; for example, you can have multiple clients that each know about only a subset of the classes the server knows. Most other libraries are monolithic, requiring all endpoints to know all types.

It has first class support for validation via Built Values. An important part of a powerful data model is ensuring it's valid, so classes can make guarantees about what they can do. Other libraries also support validation but usually in a less prominent way.

It's pluggable. You can add serializers for your own types, and you can add plugins which run before and after all serializers. This could be used to interoperate with other tools or to add hand coded high performance serializers for specific classes. Some other libraries are not so extensible.

It was designed to be multi language, mapping to equivalent object models in Java and other languages. Currently only Dart is supported. The need for other languages didn't materialize as servers are typically either written in Dart or owned by third parties. Please open an issue if you'd like to explore support in more languages.

Common Usage

While full, compiled examples are available in example/lib, a common usage example is shown here. This example assumes that you are writing a client for a JSON API representing a person that looks like the following:

{
  "id": 12345,
  "age": 35,
  "first_name": "Jimmy",
  "hobbies": ["jumping", "basketball"]
}

The corresponding dart class employing built_value might look like this. Note that it is using the @BuiltValueField annotation to map between the property name on the response and the name of the member variable in the Person class.

import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:built_collection/built_collection.dart';

part 'person.g.dart';

abstract class Person implements Built<Person, PersonBuilder> {
  static Serializer<Person> get serializer => _$personSerializer;

  int get id;

  int? get age;

  @BuiltValueField(wireName: 'first_name')
  String? get firstName;

  BuiltList<String> get hobbies;

  Person._();
  factory Person([void Function(PersonBuilder) updates]) = _$Person;
}

FAQ

How do I check a field is valid on instantiation?

The value class private constructor runs when all fields are initialized and can do arbitrary checks:

abstract class MyValue {
  MyValue._() {
    if (field < 0) {
      throw ArgumentError(field, 'field', 'Must not be negative.');
    }
  }
How do I process a field on instantiation?

Add a hook that runs immediately before a builder is built. For example, you could sort a list, so it's always sorted directly before the value is created:

abstract class MyValue {
  @BuiltValueHook(finalizeBuilder: true)
  static void _sortItems(MyValueBuilder b) =>
      b..items.sort();
How do I set a default for a field?

Add a hook that runs whenever a builder is created:

abstract class MyValue {
  @BuiltValueHook(initializeBuilder: true)
  static void _setDefaults(MyValueBuilder b) =>
      b
        ..name = 'defaultName'
        ..count = 0;
Should I check in and/or publish in the generated .g.dart files?

See the build_runner docs. You usually should not check in generated files, but you do need to publish them.

Features and bugs

Please file feature requests and bugs at the issue tracker.

카테고리

의존성

의존성 목록 7 개

소스 저장소

이 패키지를 사용하는 프로젝트

순위