File-level Privacy

File-level Privacy

About

  • Library Scope: Privacy works across files in same library
  • part/part of: Splitting libraries into files
  • Visibility: Private members shared within library
  • Organization: Logical grouping of related code

Main Topics

  1. Single-file Libraries

    • Definition: Basic privacy scope
    • Example:
      // user.dart
      class User {
        String _id; // Private to library
      }
  2. Multi-file Libraries

    • Definition: Using part directives

    • Example:

      // user.dart
      part 'user_helpers.dart';
      class User {
        String _id; // Shared across parts
      }
      
      // user_helpers.dart
      part of 'user.dart';
      extension on User {
        void _helper() {} // Accesses _id
      }
  3. Private Top-levels

    • Definition: Across library files
    • Example:
      // utils.dart
      part of main_lib;
      void _internalHelper() {} // Private to library
  4. Visibility Rules

    • Definition: What’s accessible where
    • Example:
      // file1.dart
      part of lib;
      var _secret = 42; // Accessible in file2.dart
  5. Library Organization

    • Definition: Structuring code
    • Example:
      // Good practice:
      // lib/
      //   src/ (implementation)
      //   main.dart (public exports)

How to Use

  • Large Libraries: Split into parts
  • Implementation: Put in src/
  • API: Export only public members
  • Testing: Keep tests in same library

How It Works

  1. Compilation: Treats parts as single unit
  2. Privacy: Shared within library boundary
  3. Exports: Only public members visible outside
  4. Analysis: Tools understand part relationships

Example:

// auth_library.dart
library auth;

part 'credentials.dart';
part 'sessions.dart';

class AuthClient {
  final _storage = _AuthStorage(); // From parts
}

// credentials.dart
part of auth;

class _AuthStorage { // Private to library
  String _token;
}

Conclusion

File-level privacy in Dart enables logical code organization while maintaining encapsulation through library boundaries. By using part directives and understanding library scope, developers can create well-structured codebases where private implementation details are properly hidden across multiple files.