Flutter服务组件插件pip_services3_components的使用

Flutter服务组件插件pip_services3_components的使用

组件定义

本模块是PipServices多语言微服务工具包的一部分。

该组件模块包含可以用于构建应用和服务的标准组件定义。模块包括以下包:

  • Auth - 身份验证凭据存储
  • Build - 基础工厂用于构造对象
  • Cache - 分布式缓存
  • Config - 配置读取器和管理器,主要任务是从各种存储中传递配置参数给应用程序
  • Connect - 连接发现和服务
  • Count - 性能计数器
  • Info - 上下文信息实现,负责保存进程信息并发送附加参数集
  • Lock - 分布式锁组件
  • Log - 基础日志组件,提供控制台和复合日志功能,以及开发自定义日志器的接口
  • Test - 最小的测试组件集,使测试更简单
  • Component - 根包

使用

pubspec.yaml文件中添加依赖项:

dependencies:
  pip_services3_components: ^1.0.0

然后从命令行安装包:

pub get

日志和性能计数器的使用

这里我们将使用CompositeLoggerCompositeCounters组件。它们会通过引用将调用传递给日志器和计数器。

import 'package:pip_services3_commons/src/config/ConfigParams.dart';
import 'package:pip_services3_commons/src/config/IConfigurable.dart';
import 'package:pip_services3_commons/src/refer/IReferences.dart';
import 'package:pip_services3_commons/src/refer/IReferenceable.dart';
import 'package:pip_services3_components/src/log/CompositeLogger.dart';
import 'package:pip_services3_components/src/count/CompositeCounters.dart';
import 'package:pip_services3_components/src/count/Timing.dart';

class MyComponent implements IConfigurable, IReferenceable {
  CompositeLogger _logger = CompositeLogger();
  CompositeCounters _counters = CompositeCounters();
  
  @override
  void configure(ConfigParams config) {
    _logger.configure(config);
  }
  
  @override
  void setReferences(IReferences refs) {
    _logger.setReferences(refs);
    _counters.setReferences(refs);
  }
  
  void myMethod(String correlationId, dynamic param1) {
    try {
      _logger.trace(correlationId, "Executed method mycomponent.mymethod");
      _counters.increment("mycomponent.mymethod.exec_count", 1);
      Timing timing = _counters.beginTiming("mycomponent.mymethod.exec_time");
      // 执行业务逻辑
      timing.endTiming();
    } catch (e) {
      _logger.error(correlationId, e, "Failed to execute mycomponent.mymethod");
      _counters.increment("mycomponent.mymethod.error_count", 1);
    }
  }
}

获取连接参数和凭据

我们假设引用是外部传递的。这里我们使用解析器来获取连接参数和凭据。

import 'package:pip_services3_commons/src/config/ConfigParams.dart';
import 'package:pip_services3_commons/src/config/IConfigurable.dart';
import 'package:pip_services3_commons/src/refer/IReferences.dart';
import 'package:pip_services3_commons/src/refer/IReferenceable.dart';
import 'package:pip_services3_commons/src/run/IOpenable.dart';
import 'package:pip_services3_components/src/connect/ConnectionParams.dart';
import 'package:pip_services3_components/src/connect/ConnectionResolver.dart';
import 'package:pip_services3_components/src/auth/CredentialParams.dart';
import 'package:pip_services3_components/src/auth/CredentialResolver.dart';

class MyComponent implements IConfigurable, IReferenceable, IOpenable {
  final _connectionResolver = ConnectionResolver();
  final _credentialResolver = CredentialResolver();
  bool _opened = false;

  @override
  void configure(ConfigParams config) {
    _connectionResolver.configure(config);
    _credentialResolver.configure(config);
  }

  @override
  void setReferences(IReferences refs) {
    _connectionResolver.setReferences(refs);
    _credentialResolver.setReferences(refs);
  }

  @override
  Future<void> open(String? correlationId) async {
    ConnectionParams? connection = await _connectionResolver.resolve(correlationId);

    CredentialParams? credential = await _credentialResolver.lookup(correlationId);

    if (connection != null && credential != null) {
      String? host = connection.getHost();
      int? port = connection.getPort();
      String? user = credential.getUsername();
      String? pass = credential.getPassword();
      // 使用连接和凭据进行操作
      _opened = true;
    }
  }

  @override
  Future<void> close(String? correlationId) {
    // 关闭操作
    return Future.value();
  }

  @override
  bool isOpen() {
    return _opened;
  }
}

缓存和锁定的使用

这里我们假设引用是外部传递的。

import 'package:pip_services3_commons/src/refer/Descriptor.dart';
import 'package:pip_services3_commons/src/refer/References.dart';
import 'package:pip_services3_commons/src/refer/IReferences.dart';
import 'package:pip_services3_commons/src/refer/IReferenceable.dart';
import 'package:pip_services3_components/src/lock/ILock.dart';
import 'package:pip_services3_components/src/lock/MemoryLock.dart';
import 'package:pip_services3_components/src/cache/ICache.dart';
import 'package:pip_services3_components/src/cache/MemoryCache.dart';

class MyComponent implements IReferenceable {
  ICache? _cache;
  ILock? _lock;

  @override
  void setReferences(IReferences refs) {
    _cache = refs.getOneRequired<ICache>(Descriptor('*', 'cache', '*', '*', '1.0'));
    _lock = refs.getOneRequired<ILock>(Descriptor('*', 'lock', '*', '*', '1.0'));
  }

  Future<void> myMethod(String? correlationId, dynamic param1) async {
    // 首先检查缓存中的结果
    dynamic result = await _cache!.retrieve(correlationId, 'mykey');

    // 锁定
    await _lock!.acquireLock(correlationId, 'mykey', 1000, 1000);

    // 执行处理
    // ...

    // 异步存储结果到缓存
    await _cache!.store(correlationId, 'mykey', result, 3600000);

    // 异步释放锁
    await _lock!.releaseLock(correlationId, 'mykey');
  }
}

void main() async {
  // 使用组件
  MyComponent myComponent = MyComponent();

  myComponent.setReferences(References.fromTuples([
    Descriptor('pip-services', 'cache', 'memory', 'default', '1.0'),
    MemoryCache(),
    Descriptor('pip-services', 'lock', 'memory', 'default', '1.0'),
    MemoryLock(),
  ]));

  await myComponent.myMethod(null, 'param1');
}

使用工厂创建组件

如果你需要使用定位器(描述符)创建组件,可以实现类似于下面的例子的组件工厂。

import 'package:pip_services3_components/src/build/Factory.dart';
import 'package:pip_services3_commons/src/refer/Descriptor.dart';

class MyFactory extends Factory {
  static Descriptor myComponentDescriptor = Descriptor('myservice', 'mycomponent', 'default', '*', '1.0');

  MyFactory() : super() {
    registerAsType(MyFactory.myComponentDescriptor, MyComponent);
  }
}

// 使用工厂

MyFactory myFactory = MyFactory();

MyComponent myComponent1 = myFactory.create(
    Descriptor('myservice', 'mycomponent', 'default', 'myComponent1', '1.0'));
MyComponent myComponent2 = myFactory.create(
    Descriptor('myservice', 'mycomponent', 'default', 'myComponent2', '1.0'));

开发

开发时需要安装以下前提条件:

  • Dart SDK 2
  • Visual Studio Code 或其他IDE
  • Docker

安装依赖项:

pub get

运行自动化测试:

pub run test

生成API文档:

./docgen.ps1

在提交更改前,使用Docker化构建和测试:

./build.ps1
./test.ps1
./clear.ps1

更多关于Flutter服务组件插件pip_services3_components的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter服务组件插件pip_services3_components的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用pip_services3_components服务组件插件的示例代码。请注意,pip_services3_components是一个主要用于Node.js环境的框架,但在Flutter中我们可以通过调用原生代码(如通过MethodChannel)或者借助Dart的一些第三方库来实现类似的功能。由于Flutter本身并不直接支持pip_services3_components,这里我们会展示如何通过原生插件的方式(假设你已经在Flutter中集成了原生代码支持)。

1. 设置原生插件(以Android为例)

首先,你需要在Flutter项目中添加对原生Android代码的支持。这通常意味着你需要有一个android文件夹,并且在该文件夹中有相应的Android项目结构。

Android原生代码

android/app/src/main/java/com/yourapp/YourApplication.java(或Kotlin版本)中,你可以实现pip_services3_components的功能。由于直接集成复杂,这里假设你已经有一个封装好的Java/Kotlin库,该库实现了pip_services3_components的功能,并暴露了一个简单的接口。

// YourLibrary.java
package com.yourapp;

import com.pipservices3.components.log.Logger;
import com.pipservices3.components.log.LogLevel;

public class YourLibrary {
    private Logger logger;

    public YourLibrary() {
        this.logger = new Logger("YourLibrary");
        this.logger.setLevel(LogLevel.Debug);
    }

    public String info(String message) {
        this.logger.info(message);
        return "Info logged: " + message;
    }
}

Flutter与原生交互

接下来,你需要创建一个Flutter插件来与这个原生代码交互。在lib文件夹中创建一个Dart文件,比如your_library.dart

import 'dart:async';

import 'package:flutter/services.dart';

class YourLibrary {
  static const MethodChannel _channel = const MethodChannel('com.yourapp/your_library');

  static Future<String?> info(String message) async {
    final String? result = await _channel.invokeMethod('info', message);
    return result;
  }
}

然后,在android/app/src/main/kotlin/com/yourapp/MainActivity.kt(或Java版本)中注册MethodChannel并处理调用。

// MainActivity.kt
package com.yourapp

import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.yourapp/your_library"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "info") {
                val message = call.argument<String>("message") ?: ""
                val yourLibrary = YourLibrary()
                val response = yourLibrary.info(message)
                result.success(response)
            } else {
                result.notImplemented()
            }
        }
    }
}

2. 在Flutter应用中使用

现在你可以在Flutter应用中使用这个封装好的库了。

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Demo Home Page'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: _logInfo,
            child: Text('Log Info'),
          ),
        ),
      ),
    );
  }

  void _logInfo() async {
    String? result = await YourLibrary.info("Hello from Flutter!");
    print(result);
  }
}

结论

由于pip_services3_components是一个Node.js框架,直接在Flutter中使用它是不可能的。但是,通过创建一个原生插件,你可以封装pip_services3_components的功能,并在Flutter中调用这些封装好的功能。上面的例子展示了如何在Android平台上实现这一点,iOS平台的过程类似,但需要使用Swift或Objective-C来编写原生代码。

回到顶部