Flutter中介通信插件dart_mediator的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter中介通信插件dart_mediator的使用

Mediator.dart

Dart pub package codecov

Mediator.dart是受MediatR启发为Dart实现的中介模式。这个包提供了一个简单且可配置的解决方案,用于处理请求/响应、命令、事件等。

功能特性

  • ✅ 请求/响应
  • ✅ 命令
  • ✅ 请求/命令管道
  • ✅ 事件
  • ✅ 事件观察者

使用示例

下面将通过几个具体的例子来展示如何在Flutter项目中使用dart_mediator插件。

发送事件

import 'package:dart_mediator/mediator.dart';

/// 强类型事件类包含事件数据。
/// 所有事件必须实现 [DomainEvent] 接口。
class MyEvent implements DomainEvent {}

Future<void> main() async {
  final mediator = Mediator.create();

  // 订阅事件。
  mediator.events.on<MyEvent>()
    .subscribeFunction(
      (event) => print('event received'),
    );

  // 发送事件给所有处理器。
  // 这将打印 'event received'。
  await mediator.events.dispatch(MyEvent());
}

发送命令

/// 此命令不会返回值。
class MyCommand implements Command {}

class MyCommandHandler implements CommandHandler<MyCommand> {
  @override
  FutureOr<void> handle(MyCommand request) {
    // Do something
  }
}

Future<void> main() async {
  final mediator = Mediator.create();

  mediator.requests.register(MyCommandHandler());

  /// 发送命令请求。返回值是 [void]。
  await mediator.requests.send(MyCommand());
}

发送请求

import 'package:dart_mediator/mediator.dart';

class Something {}

/// 此查询将返回一个 [Something] 对象。
class MyQuery implements Query<Something> {}

class MyQueryHandler implements QueryHandler<Something, MyQuery> {
  @override
  FutureOr<Something> handle(MyQuery request) {
    // do something
    return Something();
  }
}

Future<void> main() async {
  final mediator = Mediator.create();

  mediator.requests.register(MyQueryHandler());

  // 发送查询请求并返回响应。
  final Something response = await mediator.requests.send(MyQuery());

  print(response);
}

事件观察者

class LoggingEventObserver implements EventObserver {

  /// 当事件被分派但任何处理器还未调用时调用。
  @override
  void onDispatch<TEvent extends DomainEvent>(
    TEvent event,
    Set<EventHandler<TEvent>> handlers,
  ) {
    print(
      '[LoggingEventObserver] onDispatch "$event" with ${handlers.length} handlers',
    );
  }

  /// 当事件处理程序返回错误时调用。
  @override
  void onError<TEvent extends DomainEvent>(
    TEvent event,
    EventHandler<TEvent> handler,
    Object error,
    StackTrace stackTrace,
  ) {
    print('[LoggingEventObserver] onError $event -> $handler ($error)');
  }

  /// 当事件被处理器处理后调用。
  @override
  void onHandled<TEvent extends DomainEvent>(
    TEvent event,
    EventHandler<TEvent> handler,
  ) {
    print('[LoggingEventObserver] onHandled $event -> $handler');
  }
}

void main() {
  final mediator = Mediator.create(
    // 添加日志记录事件观察者。
    observers: [LoggingEventObserver()],
  );

  // 分派一个事件。
}

请求/命令管道行为

class LoggingBehavior implements PipelineBehavior {
  @override
  Future handle(request, RequestHandlerDelegate next) async {
    try {
      print('[$LoggingBehavior] [${request.runtimeType}] Before');
      return await next();
    } finally {
      print('[$LoggingBehavior] [${request.runtimeType}] After');
    }
  }
}

void main() {
    final mediator = Mediator.create();

    // 添加日志记录行为
    mediator.requests.pipeline.registerGeneric(LoggingBehavior());
}

完整示例代码

import 'dart:async';
import 'package:dart_mediator/mediator.dart';
import 'package:meta/meta.dart';

Future<void> main() async {
  final mediator = Mediator.create(
    observers: [LoggingEventObserver()],
  );

  // 添加请求日志记录行为。
  mediator.requests.pipeline.registerGeneric(LoggingBehavior());

  // 注册请求处理器。
  mediator.requests.register(GetUserByIdQueryHandler());
  mediator.requests.register(MyCommandHandler());

  // 订阅计数事件。
  mediator.events.on<CountEvent>().subscribeFactory(createCountEventHandler);

  mediator.events
      .on<CountEvent>()
      .distinct()
      .map((event) => event.count)
      .subscribeFunction(
    (count) {
      // 只有不同的计数事件会到达这里。
      // LoggingEventObserver仍然会看到事件。
      print('[CountEvent Handler] received distinct count: $count');
    },
  );

  print('--- Query Example ---');

  const getUserQuery = GetUserByIdQuery(123);

  print('Sending $getUserQuery request');

  final resp = await mediator.requests.send(getUserQuery);

  print('Got $getUserQuery response: $resp');

  print('\n--- Command Example ---');

  const order66Command = MyCommand('Order 66');

  print('Sending $order66Command');

  await mediator.requests.send(order66Command);

  print('$order66Command completed');

  print('\n--- Events Example ---');

  const countEvent = CountEvent(123);

  // 事件将由2个事件处理器处理。
  await mediator.events.dispatch(countEvent);

  // 事件将仅由1个事件处理器处理(不同)。
  await mediator.events.dispatch(countEvent);

  print('done');
}

@immutable
class CountEvent implements DomainEvent {
  final int count;
  const CountEvent(this.count);

  @override
  String toString() => 'CountEvent(count: $count)';

  @override
  int get hashCode => Object.hash(runtimeType, count);

  @override
  bool operator ==(Object other) {
    return identical(this, other) ||
        (other.runtimeType == runtimeType &&
            other is CountEvent &&
            other.count == count);
  }
}

class CountEventHandler implements EventHandler<CountEvent> {
  @override
  FutureOr<void> handle(CountEvent event) {
    final count = event.count;
    print('[CountEvent Handler] received count: $count');
  }
}

CountEventHandler createCountEventHandler() => CountEventHandler();

class MyCommand implements Command {
  final String command;
  const MyCommand(this.command);

  @override
  String toString() => 'MyCommand(command: $command)';
}

class MyCommandHandler implements CommandHandler<MyCommand> {
  @override
  Future<void> handle(MyCommand request) async {
    final command = request.command;
    print('[MyCommandHandler] Execute $command');
    {
      await Future.delayed(const Duration(milliseconds: 300));
      for (var i = 0; i < 3; i++) {
        print('[MyCommandHandler] pew');
        await Future.delayed(const Duration(milliseconds: 300));
      }
    }
    print('[MyCommandHandler] $request executed!');
  }
}

class GetUserByIdQuery implements Query<User> {
  final int userId;
  const GetUserByIdQuery(this.userId);

  @override
  String toString() => 'GetUserByIdQuery(userId: $userId)';
}

class GetUserByIdQueryHandler implements QueryHandler<User, GetUserByIdQuery> {
  @override
  Future<User> handle(GetUserByIdQuery request) async {
    print('[GetUserByIdQueryHandler] handling $request');
    final user = await getUserByIdAsync(request.userId);
    print('[GetUserByIdQueryHandler] got $user');
    return user;
  }
}

class LoggingBehavior implements PipelineBehavior {
  @override
  Future handle(request, RequestHandlerDelegate next) async {
    try {
      print('[LoggingBehavior] [$request] Before');
      return await next();
    } finally {
      print('[LoggingBehavior] [$request] After');
    }
  }
}

class LoggingEventObserver implements EventObserver {
  @override
  void onDispatch<TEvent>(
    TEvent event,
    Set<EventHandler> handlers,
  ) {
    print(
      '[LoggingEventObserver] onDispatch "$event" with ${handlers.length} handlers',
    );
  }

  @override
  void onError<TEvent>(
    TEvent event,
    EventHandler handler,
    Object error,
    StackTrace stackTrace,
  ) {
    print('[LoggingEventObserver] onError $event -> $handler ($error)');
  }

  @override
  void onHandled<TEvent>(
    TEvent event,
    EventHandler handler,
  ) {
    print('[LoggingEventObserver] onHandled $event handled by $handler');
  }
}

class User {
  final int id;
  final String name;

  const User(this.id, this.name);

  @override
  String toString() => 'User(id: $id, name: $name)';
}

Future<User> getUserByIdAsync(int id) async {
  await Future.delayed(const Duration(seconds: 1));
  return User(id, 'John Doe');
}

以上代码展示了如何在Flutter项目中使用dart_mediator插件进行事件、命令和请求的发送与处理。希望这些示例能帮助你更好地理解和使用该插件。


更多关于Flutter中介通信插件dart_mediator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter中介通信插件dart_mediator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter应用中,dart_mediator 是一个用于中介通信的插件,它允许在不同组件或页面之间安全、高效地传递数据。以下是一个关于如何使用 dart_mediator 的代码案例,展示了如何设置和使用中介者模式进行数据通信。

首先,确保你已经在 pubspec.yaml 文件中添加了 dart_mediator 依赖:

dependencies:
  flutter:
    sdk: flutter
  dart_mediator: ^latest_version  # 替换为最新的版本号

然后,运行 flutter pub get 来获取依赖。

设置中介者

首先,你需要创建一个中介者类,用于管理不同组件之间的通信。假设我们有一个简单的中介者,用于传递字符串消息。

import 'package:dart_mediator/dart_mediator.dart';

class MyMediator extends Mediator {
  // 定义一个事件名
  static const String messageEvent = "messageEvent";

  // 发送消息的方法
  void sendMessage(String message) {
    notifyColleagues(messageEvent, message);
  }

  // 接收消息并处理的方法(可以重写父类的onNotify方法)
  @override
  void onNotify(String event, dynamic data) {
    if (event == messageEvent) {
      // 处理接收到的消息
      print("Received message: $data");
    }
  }
}

注册中介者

在你的 Flutter 应用的主入口(通常是 main.dart)中注册中介者。

import 'package:flutter/material.dart';
import 'package:dart_mediator/dart_mediator.dart';
import 'my_mediator.dart';  // 导入你创建的中介者类

void main() {
  // 注册中介者
  MediatorFactory.registerMediator(MyMediator());

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Mediator Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              SenderWidget(),
              ReceiverWidget(),
            ],
          ),
        ),
      ),
    );
  }
}

创建发送和接收组件

接下来,创建发送和接收消息的组件。

发送组件

import 'package:flutter/material.dart';
import 'package:dart_mediator/dart_mediator.dart';

class SenderWidget extends StatefulWidget {
  @override
  _SenderWidgetState createState() => _SenderWidgetState();
}

class _SenderWidgetState extends State<SenderWidget> {
  final TextEditingController _controller = TextEditingController();

  void _sendMessage() {
    // 获取中介者实例
    final MyMediator mediator = MediatorFactory.getMediator<MyMediator>();
    // 发送消息
    mediator.sendMessage(_controller.text);
    // 清空文本框
    _controller.clear();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        TextField(
          controller: _controller,
          decoration: InputDecoration(labelText: 'Enter message'),
        ),
        SizedBox(height: 10),
        ElevatedButton(
          onPressed: _sendMessage,
          child: Text('Send Message'),
        ),
      ],
    );
  }
}

接收组件

import 'package:flutter/material.dart';
import 'package:dart_mediator/dart_mediator.dart';
import 'my_mediator.dart';  // 导入中介者类以便访问事件名

class ReceiverWidget extends StatefulWidget {
  @override
  _ReceiverWidgetState createState() => _ReceiverWidgetState();
}

class _ReceiverWidgetState extends State<ReceiverWidget> {
  String _message = "";

  @override
  void initState() {
    super.initState();
    // 获取中介者实例并监听事件
    final MyMediator mediator = MediatorFactory.getMediator<MyMediator>();
    mediator.registerListener(MyMediator.messageEvent, (event, data) {
      setState(() {
        _message = data;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Text(
      _message.isEmpty ? 'No message received yet.' : 'Received: $_message',
      style: TextStyle(fontSize: 20),
    );
  }
}

以上代码展示了如何使用 dart_mediator 插件在 Flutter 应用中实现中介者模式的通信。发送组件通过中介者发送消息,接收组件通过中介者监听并处理消息。这样,不同组件之间的通信就变得清晰、解耦且易于管理。

回到顶部