Migrating to v2#

The v2 release of the clean_framework is more optimized, easier to use, with better error reporting. This guide will help you migrate your existing code use the v2 of the package.

Gradual Migration#

If you want to migrate your project to v2 gradually, you can do so by following these steps:

  • Update your pubspec.yaml file to use the latest version of clean_framework.
  • The new package:clean_framework/clean_framework.dart exports new classes for clean_framework which can conflict with the old classes. To avoid this, replace all the imports for package:clean_framework/clean_framework.dart & package:clean_framework/clean_framework_providers.dart with package:clean_framework/clean_framework_legacy.dart.
  • If you were using package:clean_framework/clean_framework_defaults.dart, all the classes from defaults have been moved into sub-package. So, please add the necessary sub-packages and import the classes from there.

Migrating Use Case#

The inputFilters & outputFilters are now deprecated in favor of transformers.

// Before
class HomeUseCase extends UseCase<HomeEntity> {
  HomeUseCase()
      : super(
          entity: HomeEntity(),
          outputFilters: {
            FooOutput: (entity) => FooOutput(entity.foo),
            BarOutput: (entity) => BarOutput(entity.bar),
          },
          inputFilters: {
            FooInput: (input, entity) {
              return entity.copyWith(foo: (input as FooInput).foo);
            },
          },
        );

  ...
}

// After
class HomeUseCase extends UseCase<HomeEntity> {
  HomeUseCase()
      : super(
          entity: HomeEntity(),
          transformers: [
            FooOutputTransformer(),
            BarOutputTransformer(),
            FooInputTransformer(),
          ],
        );

  ...
}

See use_case_transformer_test.dart for more details.

Migrating Gateways#

The gateways no longer requires to hold the associated use case providers as it's now attached through the gateway provider itself.

// Before
class MyGateway extends Gateway {
  MyGateway()
      : super(
          context: providersContext,
          provider: featureUseCaseProvider,
        );

 ...
}

// After
class MyGateway extends Gateway {
 ...
}

Migrating External Interfaces#

The external interfaces no longer requires to have gateway connection as it's now done by the external interface provider itself.

// Before
class MyExternalInterface extends ExternalInterface {
  MyExternalInterface(): super(
    gatewayConnections: [
      () => myGatewayProvider.getGateway(providersContext),
    ],
  );

  ...
}

// After
class MyExternalInterface extends ExternalInterface {
  ...
}

Migrating Providers#

The providers are now much simpler and easier to use. And manually initializing the providers is no longer required.

/// Before
final myUseCaseProvider = UseCaseProvider((_) => LastLoginUseCase());

final myGatewayProvider = GatewayProvider((_) => LastLoginDateGateway());

final myExternalInterface = ExternalInterfaceProvider(
  (_) => MyExternalInterface(
    gatewayConnections: [
      () => myGatewayProvider.getGateway(providersContext),
    ],
  ),
);

void loadProviders(){
  myUseCaseProvider.getUseCaseFromContext(providersContext);
  myGatewayProvider.getGateway(providersContext);
  myExternalInterface.getExternalInterface(providersContext);
}

/// After
final myUseCaseProvider = UseCaseProvider(MyUseCase.new);

final myGateway = GatewayProvider(
  MyGateway.new,
  useCases: [myUseCaseProvider],
);

final myExternalInterfaceProvider = ExternalInterfaceProvider(
  MyExternalInterface.new,
  gateways: [mynGatewayProvider],
);

Migrating AppProvidersContainer#

To more align with Riverpod and other scoped widgets used by the framework. The AppProvidersContainer has been renamed to AppProviderScope.

/// Before
loadProviders();

AppProvidersContainer(
  providersContext: providersContext,
  child: MyApp(),
);

/// After
AppProviderScope(
  child: MyApp(),
);