diff --git a/config/module.config.php b/config/module.config.php
index 6728db754d26922f5bef04b046f276e0c7f4feaa..8a103dddbb5f4dcc6889a14e9d28b597293ec92e 100644
--- a/config/module.config.php
+++ b/config/module.config.php
@@ -35,7 +35,7 @@ return [
         ],
 
         'migration' => [
-            'dir' => null,
+            // array des classes ou services utilisés pour la migration [index => classe ou service, ...]
         ],
 
         'id_column' => 'id',
diff --git a/src/Bdd.php b/src/Bdd.php
index f72df18378d0a45fd61416796ceaf709916694a5..d2551ea0189686e57732585dd461e65cc54a97dd 100644
--- a/src/Bdd.php
+++ b/src/Bdd.php
@@ -398,7 +398,8 @@ class Bdd
     public function migration(): MigrationManager
     {
         if (!isset($this->migration)) {
-            $this->migration = new MigrationManager($this);
+            $this->migration = new MigrationManager();
+            $this->migration->setBdd($this);
             $this->migration->setOptions($this->getOption(self::OPTION_MIGRATION, []));
         }
 
@@ -504,10 +505,10 @@ class Bdd
         $filters->addArray($ddl->getOption(Ddl::OPTION_FILTERS));
         $filters->addArray($ddl->getOption(Ddl::OPTION_UPDATE_BDD_FILTERS));
         $filters->setExplicit(true);
-        
+
         // On ajouter toute la DDL qu'on donne en référence
         $filters->addDdl($ddl);
-        
+
         // On ajoute toutes les dépendances des tables qu'on a inclu dans la DDL au cas où elles ne seraient pas listées
         $filters->addTablesDeps($this);
 
@@ -519,8 +520,8 @@ class Bdd
     public function getFiltersForUpdateDdl(): DdlFilters
     {
         $filters = new DdlFilters();
-        $filters->addArray($this->getOption(self::OPTION_DDL.'/'.Ddl::OPTION_FILTERS));
-        $filters->addArray($this->getOption(self::OPTION_DDL.'/'.Ddl::OPTION_UPDATE_DDL_FILTERS));
+        $filters->addArray($this->getOption(self::OPTION_DDL . '/' . Ddl::OPTION_FILTERS));
+        $filters->addArray($this->getOption(self::OPTION_DDL . '/' . Ddl::OPTION_UPDATE_DDL_FILTERS));
 
         return $filters;
     }
@@ -531,17 +532,17 @@ class Bdd
     {
         $ddl = new Ddl();
         $ddl->setOptions($this->getOption(self::OPTION_DDL, []));
-        
+
         return $ddl;
     }
-    
-    
+
+
 
     public function getDdl(DdlFilters|array $filters = []): Ddl
     {
         $this->logBegin("Récupération de la DDL");
-        $filters = DdlFilters::normalize($filters);
-        $ddl     = $this->getNewDdl();
+        $filters  = DdlFilters::normalize($filters);
+        $ddl      = $this->getNewDdl();
         $managers = $this->managerList();
         foreach ($managers as $type => $libelle) {
             if (!($filters->isExplicit() && $filters->get($type)->isEmpty())) {
@@ -667,7 +668,6 @@ class Bdd
                 }
             }
         }
-        $this->compilerTout();
     }
 
 
@@ -685,9 +685,6 @@ class Bdd
             $ddl = Ddl::normalize($ddl)->filter($filters);
         }
 
-        $this->migration()->init($ddl, $filters);
-        $this->migration()->migration('before');
-
         foreach ($this->changements as $changement => $label) {
             [$ddlName, $action] = explode('.', $changement);
 
@@ -718,13 +715,11 @@ class Bdd
             }
         }
         $this->logEnd();
-        $this->compilerTout();
-        $this->migration()->migration('after');
     }
 
 
 
-    public function drop(DdlFilters|array $filters = []): void
+    public function drop(DdlFilters|array $filters = []): self
     {
         $filters = DdlFilters::normalize($filters);
 
@@ -753,7 +748,125 @@ class Bdd
                 }
             }
         }
-        $this->logEnd();
+        return $this;
+    }
+
+
+
+    public function clear(): self
+    {
+        $this->logTitle('Vidage complet de la base de données');
+        try {
+            $this->drop();
+        } catch (\Throwable $e) {
+            $this->logError($e);
+        }
+        $this->logSuccess('Base de données vidée complètement');
+        return $this;
+    }
+
+
+
+    public function install(): self
+    {
+        $this->logTitle('Installation de la base de données');
+
+        // Mise en place des objets
+        try {
+            $ddl = $this->getRefDdl();
+            $this->create($ddl);
+            $this->logSuccess('Objets en place');
+        } catch (\Throwable $e) {
+            $this->logError($e);
+        }
+
+        if (!empty($this->data()->getSources())) {
+            // Installation des données
+            $this->logTitle('Insertion du jeu de données données');
+            try {
+                $this->data()->run(DataManager::ACTION_INSTALL);
+                $this->logSuccess('Données écrites');
+            } catch (\Throwable $e) {
+                $this->logError($e);
+            }
+        }
+
+        return $this;
+    }
+
+
+
+    public function update(): self
+    {
+        $this->logTitle('Mise à jour de la base de données');
+
+        $ddl     = $this->getRefDdl();
+        $filters = $this->getFiltersForUpdateBdd($ddl);
+
+        // Initialisation et lancement de la pré-migration
+        $migrationManager = $this->migration();
+
+        $migrationManager->init($ddl, $filters);
+        $migrationManager->run(MigrationManager::ACTION_BEFORE);
+
+
+        try {
+            $this->alter($ddl, $filters, true);
+            $this->logSuccess('Objets à jour');
+        } catch (\Throwable $e) {
+            $this->logError($e);
+        }
+
+        // On compile tout
+        $this->compilerTout();
+
+
+        // Mise à jour des séquences
+        $this->majSequences($ddl);
+
+
+        // Mise à jour des données
+        $this->updateData();
+
+
+        // Post-migration
+        $migrationManager->run(MigrationManager::ACTION_AFTER);
+
+        return $this;
+    }
+
+
+
+    public function updateData(): self
+    {
+        if (!empty($this->data()->getSources())) {
+            $this->logTitle('Contrôle et mise à jour des données');
+            try {
+                $this->data()->run(DataManager::ACTION_UPDATE);
+                $this->logSuccess('Données à jour');
+            } catch (\Throwable $e) {
+                $this->logError($e);
+            }
+        }
+        return $this;
+    }
+
+
+
+    public function updateDdl(): self
+    {
+        $this->logTitle('Génération de la DDL à partir de la base de données');
+
+        try {
+            $filters = $bdd->getFiltersForUpdateDdl();
+            $ddl     = $bdd->getDdl($filters);
+            $ddl->saveToDir();
+            $this->logSuccess('DDL mise à jour');
+        } catch (\Throwable $e) {
+            $this->logError($e);
+        }
+
+        return $this;
     }
 
 
@@ -923,8 +1036,11 @@ class Bdd
 
 
 
-    public function copy(Bdd $source, DdlFilters|array $filters = [], array $fncs = []): self
+    public function copy(Bdd|string $source, DdlFilters|array $filters = [], array $fncs = []): self
     {
+        if (is_string($source)) {
+            $source = $this->getBdd($source);
+        }
         if ($this->getLogger() && !$source->getLogger()) {
             $source->setLogger($this->getLogger());
         }
@@ -978,6 +1094,18 @@ class Bdd
 
 
 
+    public function copyTo(string|Bdd $destination, DdlFilters|array $filters = [], array $fncs = []): self
+    {
+        if (is_string($destination)) {
+            $destination = $this->getBdd($destination);
+        }
+        $destination->copy($this, $filters, $fncs);
+
+        return $this;
+    }
+
+
+
     public function save(string $filename, DdlFilters|array $filters = [], array $fncs = []): void
     {
         $this->logBegin("Sauvegarde de la base de données");
diff --git a/src/BddFactory.php b/src/BddFactory.php
index e4c275b2ac35b131ea713ee863af71ccc77f51d6..04d46dc9fb1590b42960322f6dce48b54af1054a 100644
--- a/src/BddFactory.php
+++ b/src/BddFactory.php
@@ -22,6 +22,11 @@ class BddFactory
      */
     public function __invoke(ContainerInterface $container, $requestedName, $options = null): Bdd
     {
+        if (Bdd::class == $requestedName){
+            $configKey = 'unicaen-bddadmin';
+        }else{
+            $configKey = $requestedName;
+        }
         $config = $container->get('config')['unicaen-bddadmin'];
 
         $bdd = new Bdd($this->prepareConfig($config, $container));
@@ -31,8 +36,9 @@ class BddFactory
 
 
 
-    public function prepareConfig(array $config, ContainerInterface $container): array
+    protected function prepareConfig(array $config, ContainerInterface $container): array
     {
+        // Chargement des sources de données depuis le ServiceManager si nécessaire
         if (isset($config[Bdd::OPTION_DATA][DataManager::OPTION_SOURCES])){
             $sources = &$config[Bdd::OPTION_DATA][DataManager::OPTION_SOURCES];
             foreach( $sources as $index => $source){
@@ -42,6 +48,16 @@ class BddFactory
             }
         }
 
+        // Chargement des scripts de migration depuis le ServiceManager si nécessaire
+        if (isset($config[Bdd::OPTION_MIGRATION])){
+            $sources = &$config[Bdd::OPTION_MIGRATION];
+            foreach( $sources as $index => $source){
+                if ($container->has($source)){
+                    $sources[$index] = $container->get($source);
+                }
+            }
+        }
+
         return $config;
     }
 }
\ No newline at end of file
diff --git a/src/Command/ClearBddCommand.php b/src/Command/ClearBddCommand.php
index ecbe5fdc2bba3982a8d07ee947fe42d08aba9f5d..65db9dd4a48caa15c2126c1838c9efe7f6a8ddeb 100644
--- a/src/Command/ClearBddCommand.php
+++ b/src/Command/ClearBddCommand.php
@@ -24,14 +24,7 @@ class ClearBddCommand extends Command
         $io  = new SymfonyStyle($input, $output);
         $bdd = $this->getBdd()->setLogger($io);
 
-        $io->title('Vidage complet de la base de données');
-
-        try {
-            $bdd->drop();
-            $io->success('Base de données vidée complètement');
-        } catch (\Throwable $e) {
-            $io->error($e->getMessage());
-        }
+        $bdd->drop();
 
         return Command::SUCCESS;
     }
diff --git a/src/Command/InstallBddCommand.php b/src/Command/InstallBddCommand.php
index ddb028c1eeb8bb82557bb39cfe86455391d39723..add9613c3edf4cc5e8e2a278882f90731e3cbcb0 100644
--- a/src/Command/InstallBddCommand.php
+++ b/src/Command/InstallBddCommand.php
@@ -24,27 +24,7 @@ class InstallBddCommand extends Command
         $io  = new SymfonyStyle($input, $output);
         $bdd = $this->getBdd()->setLogger($io);
 
-        $io->title('Installation de la base de données');
-
-        // Mise en place des objets
-        try {
-            $ddl = $bdd->getRefDdl();
-            $bdd->create($ddl);
-            $io->success('Objets en place');
-        } catch (\Throwable $e) {
-            $io->error($e->getMessage());
-        }
-
-        if (!empty($bdd->data()->getSources())) {
-            // Installation des données
-            $io->title('Insertion du jeu de données données');
-            try {
-                $bdd->data()->run(DataManager::ACTION_INSTALL);
-                $io->success('Données écrites');
-            } catch (\Throwable $e) {
-                $io->error($e->getMessage());
-            }
-        }
+        $bdd->install();
 
         return Command::SUCCESS;
     }
diff --git a/src/Command/UpdateBddCommand.php b/src/Command/UpdateBddCommand.php
index 451603fe257f0d0153b20cea59dfdbc63224552b..f3977b04404391f9dabc09f14bd442442e5f16ab 100644
--- a/src/Command/UpdateBddCommand.php
+++ b/src/Command/UpdateBddCommand.php
@@ -9,6 +9,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
 use Unicaen\BddAdmin\BddAwareTrait;
 use Unicaen\BddAdmin\Data\DataManager;
 use Unicaen\BddAdmin\Ddl\Ddl;
+use Unicaen\BddAdmin\Migration\MigrationManager;
 
 /**
  * Description of UpdateBddCommand
@@ -24,42 +25,7 @@ class UpdateBddCommand extends Command
         $io  = new SymfonyStyle($input, $output);
         $bdd = $this->getBdd()->setLogger($io);
 
-        $io->title('Mise à jour de la base de données');
-
-        $ddl = $bdd->getRefDdl();
-        $filters = $bdd->getFiltersForUpdateBdd($ddl);
-
-        // Initialisation et lancement de la pré-migration
-        //$mm = new MigrationManager($oa, $ddl, $filters);
-        //$mm->migration('before');
-
-
-        try {
-            $bdd->alter($ddl, $filters, true);
-            $io->success('Objets à jour');
-        } catch (\Throwable $e) {
-            $io->error($e->getMessage());
-        }
-
-
-        // Mise à jour des séquences
-        $bdd->majSequences($ddl);
-
-
-        // Mise à jour des données
-        if (!empty($bdd->data()->getSources())) {
-            $io->title('Contrôle et mise à jour des données');
-            try {
-                $bdd->data()->run(DataManager::ACTION_UPDATE);
-                $io->success('Données à jour');
-            } catch (\Throwable $e) {
-                $io->error($e->getMessage());
-            }
-        }
-
-
-        // Post-migration
-        //$mm->migration('after');
+        $bdd->update();
 
         return Command::SUCCESS;
     }
diff --git a/src/Command/UpdateDataCommand.php b/src/Command/UpdateDataCommand.php
index 4913b9c43169cd3d502e0f20483ad7ed41220b44..d1ef14363c5080c431be12da597499302643e202 100644
--- a/src/Command/UpdateDataCommand.php
+++ b/src/Command/UpdateDataCommand.php
@@ -23,18 +23,7 @@ class UpdateDataCommand extends Command
         $io = new SymfonyStyle($input, $output);
         $bdd = $this->getBdd()->setLogger($io);
 
-        // Mise à jour des données
-        if (!empty($bdd->data()->getSources())) {
-            $io->title('Contrôle et mise à jour des données');
-            try {
-                $bdd->data()->run('update');
-                $io->success('Données à jour');
-            } catch (\Throwable $e) {
-                $io->error($e->getMessage());
-            }
-        }else{
-            $io->error('Aucune source de donnée fournie');
-        }
+        $bdd->updateData();
 
         return Command::SUCCESS;
     }
diff --git a/src/Command/UpdateDdlCommand.php b/src/Command/UpdateDdlCommand.php
index ae127d8e97cb3230b4d8272083e53e16a2175431..75e18777ce329b25cc36853fed3b1836c05435a8 100644
--- a/src/Command/UpdateDdlCommand.php
+++ b/src/Command/UpdateDdlCommand.php
@@ -22,16 +22,7 @@ class UpdateDdlCommand extends Command
         $io  = new SymfonyStyle($input, $output);
         $bdd = $this->getBdd()->setLogger($io);
 
-        $io->title('Génération de la DDL à partir de la base de données');
-
-        try {
-            $filters = $bdd->getFiltersForUpdateDdl();
-            $ddl = $bdd->getDdl($filters);
-            $ddl->saveToDir();
-            $io->success('DDL mise à jour');
-        } catch (\Throwable $e) {
-            $io->error($e->getMessage());
-        }
+        $bdd->updateDdl();
 
         return Command::SUCCESS;
     }
diff --git a/src/Logger/DefaultLogger.php b/src/Logger/DefaultLogger.php
index 4846a4917fd1fad32c667d896d56ea35d1c83244..1c82933a742114bc19179d43e409ee6bbaa820c2 100644
--- a/src/Logger/DefaultLogger.php
+++ b/src/Logger/DefaultLogger.php
@@ -7,6 +7,7 @@ class DefaultLogger implements LoggerInterface
 {
     const COLOR_LIGHT_RED = '1;31';
     const COLOR_LIGHT_PURPLE = '1;35';
+    const COLOR_LIGHT_GREEN  = '1;32';
 
 
     protected ?string $lastMessage = null;
@@ -15,7 +16,7 @@ class DefaultLogger implements LoggerInterface
 
 
 
-    public function print($text, $color = null, $bgColor = null)
+    public function print($text, $color = null, $bgColor = null): void
     {
         if ($bgColor) $bgColor = ';' . $bgColor;
 
@@ -28,7 +29,7 @@ class DefaultLogger implements LoggerInterface
 
 
 
-    public function println($text, $color = null, $bgColor = null)
+    public function println($text, $color = null, $bgColor = null): void
     {
         $this->print($text, $color, $bgColor);
         echo "\n";
@@ -36,7 +37,7 @@ class DefaultLogger implements LoggerInterface
 
 
 
-    public function msg($message, bool $rewrite = false)
+    public function msg($message, bool $rewrite = false): void
     {
         if ($rewrite) {
             if ($this->lastMessage) {
@@ -54,7 +55,32 @@ class DefaultLogger implements LoggerInterface
 
 
 
-    public function error(Throwable|string $e)
+    public function title(string $title): void
+    {
+        $spaces = 1;
+        $pstr = str_repeat(' ', $spaces);
+        $t    = $pstr . $title . $pstr;
+
+        $len = mb_strlen($t);
+
+        echo '╔' . str_repeat('═', $len) . "╗\n";
+        echo '║' . str_repeat(' ', $len) . "║\n";
+        echo "║" . $t . "║\n";
+        echo '║' . str_repeat(' ', $len) . "║\n";
+        echo '╚' . str_repeat('═', $len) . "╝\n\n";
+    }
+
+
+
+    public function success(string $message): void
+    {
+        if ($this->lastRewrite) $this->println('');
+        $this->println($message, self::COLOR_LIGHT_GREEN);
+    }
+    
+    
+
+    public function error(Throwable|string $e): void
     {
         if ($e instanceof \Throwable) {
             $e = $e->getMessage();
@@ -65,7 +91,7 @@ class DefaultLogger implements LoggerInterface
 
 
 
-    public function begin(string $title)
+    public function begin(string $title): void
     {
         if ($this->lastMessage) {
             $title .= str_pad('', strlen($this->lastMessage) - strlen($title) + 2);
diff --git a/src/Logger/LoggerAwareTrait.php b/src/Logger/LoggerAwareTrait.php
index 399a64ed6758ee734dcd637760ef53f5c842cf53..b92294a96beaf3da08b06a580e0c3ef2fc092b66 100644
--- a/src/Logger/LoggerAwareTrait.php
+++ b/src/Logger/LoggerAwareTrait.php
@@ -38,28 +38,40 @@ trait LoggerAwareTrait
 
 
 
-    public function logError($e)
+    public function logTitle(string $title): void
+    {
+        if ($this->logger) $this->logger->title($title);
+    }
+
+
+    public function logSuccess(string $message): void
+    {
+        if ($this->logger) $this->logger->success($message);
+    }
+
+
+    public function logError(string|\Throwable $e): void
     {
         if ($this->logger) $this->logger->error($e);
     }
 
 
 
-    public function logBegin(string $title)
+    public function logBegin(string $title): void
     {
         if ($this->logger) $this->logger->begin($title);
     }
 
 
 
-    public function logEnd(?string $msg = null)
+    public function logEnd(?string $msg = null): void
     {
         if ($this->logger) $this->logger->end($msg);
     }
 
 
 
-    public function logMsg($message, bool $rewrite = false)
+    public function logMsg(string $message, bool $rewrite = false): void
     {
         if ($this->logger) $this->logger->msg($message, $rewrite);
     }
diff --git a/src/Logger/LoggerInterface.php b/src/Logger/LoggerInterface.php
index 0d0aa4bf545a7fa0cc6210b3cc84243bcb57f349..d7b5940df7209fc94680e6774f5df8307b902602 100644
--- a/src/Logger/LoggerInterface.php
+++ b/src/Logger/LoggerInterface.php
@@ -4,17 +4,25 @@ namespace Unicaen\BddAdmin\Logger;
 
 interface LoggerInterface
 {
-    public function error(Throwable|string $e);
+    public function title(string $title): void;
 
 
 
-    public function begin(string $title);
+    public function success(string $message): void;
 
 
 
-    public function end(?string $msg = null);
+    public function error(Throwable|string $e): void;
 
 
 
-    public function msg($message, bool $rewrite = false);
+    public function begin(string $title): void;
+
+
+
+    public function end(?string $msg = null): void;
+
+
+
+    public function msg($message, bool $rewrite = false): void;
 }
\ No newline at end of file
diff --git a/src/Logger/SymfonyStyleLogger.php b/src/Logger/SymfonyStyleLogger.php
index 1177c49d660ffc9feac146aa4b20aac73ec0d6c5..9e1ee50386bdbbba36819e8a9baee503024e4e1e 100644
--- a/src/Logger/SymfonyStyleLogger.php
+++ b/src/Logger/SymfonyStyleLogger.php
@@ -10,7 +10,7 @@ class SymfonyStyleLogger implements LoggerInterface
     protected ?string $lastMessage = null;
 
     protected bool $lastRewrite = false;
-    
+
     protected SymfonyStyle $symfonyStyle;
 
 
@@ -22,21 +22,21 @@ class SymfonyStyleLogger implements LoggerInterface
 
 
 
-    public function print($text, $color = null, $bgColor = null)
+    public function print($text, $color = null, $bgColor = null): void
     {
         $this->symfonyStyle->write($text);
     }
 
 
 
-    public function println($text, $color = null, $bgColor = null)
+    public function println($text, $color = null, $bgColor = null): void
     {
         $this->symfonyStyle->writeln($text);
     }
 
 
 
-    public function msg($message, bool $rewrite = false)
+    public function msg($message, bool $rewrite = false): void
     {
         if ($rewrite) {
             if ($this->lastMessage) {
@@ -54,7 +54,22 @@ class SymfonyStyleLogger implements LoggerInterface
 
 
 
-    public function error(Throwable|string $e)
+    public function title(string $title): void
+    {
+        $this->symfonyStyle->title($title);
+    }
+
+
+
+    public function success(string $message): void
+    {
+        if ($this->lastRewrite) $this->println('');
+        $this->symfonyStyle->success($message);
+    }
+
+
+
+    public function error(Throwable|string $e): void
     {
         if ($e instanceof \Throwable) {
             $e = $e->getMessage();
@@ -65,7 +80,7 @@ class SymfonyStyleLogger implements LoggerInterface
 
 
 
-    public function begin(string $title)
+    public function begin(string $title): void
     {
         if ($this->lastMessage) {
             $title .= str_pad('', strlen($this->lastMessage) - strlen($title) + 2);
diff --git a/src/Migration/AbstractMigration.php b/src/Migration/MigrationAction.php
similarity index 53%
rename from src/Migration/AbstractMigration.php
rename to src/Migration/MigrationAction.php
index 20603f6e0dd48cf4ddd5ec7a1b47e6dd8cb919b7..5822a1b0c08dffb99a7f91bf8756305e2bb06c41 100644
--- a/src/Migration/AbstractMigration.php
+++ b/src/Migration/MigrationAction.php
@@ -3,19 +3,30 @@
 namespace Unicaen\BddAdmin\Migration;
 
 
-abstract class AbstractMigration
+use Unicaen\BddAdmin\BddAwareTrait;
+use Unicaen\BddAdmin\Logger\LoggerAwareTrait;
+
+abstract class MigrationAction
 {
+    use BddAwareTrait;
+    use LoggerAwareTrait;
 
-    /**
-     * @var MigrationManager
-     */
-    protected $manager;
+    private MigrationManager $manager;
 
 
 
     public function __construct(MigrationManager $manager)
     {
         $this->manager = $manager;
+        $this->setBdd($this->manager->getBdd());
+        $this->setLogger($this->getBdd()->getLogger());
+    }
+
+
+
+    protected function manager(): MigrationManager
+    {
+        return $this->manager;
     }
 
 
diff --git a/src/Migration/MigrationManager.php b/src/Migration/MigrationManager.php
index f0b5569fe43417fcf8d5c90b129c690ce768a10e..216f32bc815f39a606c99c5f3614954f0cbd150b 100644
--- a/src/Migration/MigrationManager.php
+++ b/src/Migration/MigrationManager.php
@@ -3,6 +3,7 @@
 namespace Unicaen\BddAdmin\Migration;
 
 use Unicaen\BddAdmin\Bdd;
+use Unicaen\BddAdmin\BddAwareTrait;
 use Unicaen\BddAdmin\Ddl\Ddl;
 use Unicaen\BddAdmin\Ddl\DdlFilters;
 use Unicaen\BddAdmin\Trait\OptionsTrait;
@@ -10,8 +11,10 @@ use Unicaen\BddAdmin\Trait\OptionsTrait;
 class MigrationManager
 {
     use OptionsTrait;
+    use BddAwareTrait;
 
-    const OPTION_DIR = 'dir';
+    const ACTION_BEFORE = 'before';
+    const ACTION_AFTER  = 'after';
 
     protected Ddl $ref;
 
@@ -19,40 +22,10 @@ class MigrationManager
 
     protected DdlFilters $filters;
 
-    protected Bdd $bdd;
-
     private array $actions = [];
 
 
 
-    public function __construct(Bdd $bdd)
-    {
-        $this->bdd = $bdd;
-    }
-
-
-
-    public function getDir(): ?string
-    {
-        return $this->getOption(self::OPTION_DIR);
-    }
-
-
-
-    public function setDir(?string $dir): MigrationManager
-    {
-        return $this->setOption(self::OPTION_DIR, $dir);
-    }
-
-
-
-    public function getBdd(): Bdd
-    {
-        return $this->bdd;
-    }
-
-
-
     /**
      * Retourne la nouvelle DDL de la base de données
      */
@@ -172,97 +145,66 @@ class MigrationManager
 
 
 
-    protected function getMigrationDir(): ?string
+    public function init(Ddl $ref, DdlFilters|array $filters = [])
     {
-        $migrationDir = $this->getBdd()->getOption(self::OPTION_DIR);
-
-        return $migrationDir;
+        $this->ref     = $ref;
+        $this->filters = DdlFilters::normalize($filters);
+        $this->old     = $this->getBdd()->getDdl($this->filters);
     }
 
 
 
-    protected function getMigrationObject(string $action): ?AbstractMigration
+    /**
+     * @return array|MigrationAction[]
+     * @throws \Exception
+     */
+    public function getScripts(): array
     {
-        if (!array_key_exists($action, $this->actions)) {
-            $file = $this->getMigrationDir() . $action . '.php';
-            require_once $file;
-
-            /**
-             * @var $object AbstractMigration
-             */
-            $object = new $action($this, $this);
-            if ($object->utile()) {
-                $this->actions[$action] = $object;
-            } else {
-                $this->actions[$action] = null;
-            }
-        }
-
-        return $this->actions[$action];
-    }
-
+        $scripts = $this->getOptions();
 
+        foreach ($scripts as $index => $script) {
+            if (is_string($script) && class_exists($script)) {
+                $script          = new $script($this);
+                $scripts[$index] = $script;
+            }
+            if (!$script instanceof MigrationAction) {
+                throw new \Exception('Le script de migration ' . $script::class . ' doit correspondre à une classe héritée de ' . MigrationAction::class);
+            }
 
-    protected function runMigrationAction(string $contexte, string $action): void
-    {
-        $logger = $this->getBdd()->getLogger();
-
-        $migration = $this->getMigrationObject($action);
-        if (
-            $migration
-            && $migration instanceof AbstractMigration
-            && (method_exists($migration, $contexte))
-        ) {
-            $traducs     = [
-                'before' => 'AVANT',
-                'after'  => 'APRES',
-            ];
-            $contexteLib = $traducs[$contexte] ?? $contexte;
-            $logger->msg("[$contexteLib MIGRATION] " . $migration->description() . ' ... ');
-            try {
-                $migration->$contexte();
-                $logger->msg("OK\n");
-            } catch (\Throwable $e) {
-                $logger->error($e);
+            if (!method_exists($script, self::ACTION_BEFORE) && !method_exists($script, self::ACTION_AFTER)) {
+                throw new \Exception('Le script de migration ' . $script::class . ' doit avoir une ou des méthodes ' . self::ACTION_BEFORE . ' et/ou ' . self::ACTION_AFTER);
             }
         }
-    }
-
-
-
-    public function testUtile($action): bool
-    {
-        $migration = $this->getMigrationObject($action);
 
-        return $migration instanceof AbstractMigration;
+        return $scripts;
     }
 
 
 
-    public function init(Ddl $ref, DdlFilters|array $filters = [])
+    public function run(string $context): void
     {
-        $this->ref     = $ref;
-        $this->filters = DdlFilters::normalize($filters);
-        $this->old     = $this->getBdd()->getDdl($this->filters);
-    }
-
-
-
-    public function migration(string $context = 'pre', string $action = null): void
-    {
-        $migrationDir = $this->getMigrationDir();
-
-        if (!is_dir($migrationDir ?? '')) return;
-        $files = scandir($migrationDir);
-        sort($files);
+        if ($context != self::ACTION_BEFORE && $context != self::ACTION_AFTER) {
+            throw new \Exception('Le contexte de migration ' . $context . ' est non conforme');
+        }
 
-        foreach ($files as $i => $file) {
-            if ($file == '.' || $file == '..') {
-                continue;
-            }
-            $fileAction = substr($file, 0, -4); // on supprime l'extension PHP
-            if ($action === null || $fileAction === $action) {
-                $this->runMigrationAction($context, $fileAction);
+        $scripts = $this->getScripts();
+
+        $traducs = [
+            self::ACTION_BEFORE => 'AVANT',
+            self::ACTION_AFTER  => 'APRES',
+        ];
+
+        foreach ($scripts as $object) {
+            if (method_exists($object, $context)) {
+                if ($object->utile()) {
+                    $object->logMsg("[" . $traducs[$context] . " MIGRATION] " . $object->description() . ' ... ');
+                    try {
+                        $object->$context();
+                        $object->logMsg("OK\n");
+                    } catch (\Throwable $e) {
+                        $object->logError($e);
+                    }
+                }
             }
         }
     }