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(),
);