### 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`.

```dart
// 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](https://github.com/AcmeSoftwareLLC/clean_framework/blob/develop/packages/clean_framework/test/core/use_case/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.

```dart
// 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.

```dart
// 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.

```dart
/// 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`.

```dart
/// Before
loadProviders();

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

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