Skip to content

Conversation

DuckThom
Copy link
Contributor

  • Resolve migration classes via the container to allow DI in migrations

@driesvints driesvints changed the title Resolve migration classes via the container [6.x] Resolve migration classes via the container Nov 14, 2019
$class = Str::studly(implode('_', array_slice(explode('_', $file), 4)));

return new $class;
return resolve($class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't use a global foundation helper here. This couples the database component directly to the framework and will prevent it from being used outside of it.

@driesvints
Copy link
Member

Can you maybe explain more in detail why this is needed? Provide some use cases.

@DuckThom
Copy link
Contributor Author

@driesvints

Personally, I'm not a big fan of using Facades, so in our apps we tend use DI everywhere to inject our classes, with the exception being our migrations. Aside from this, I'd say having the possibility to use DI here would never be a bad thing considering it's possible to use it virtually everywhere else as well.

As for the global helper, I forgot that illuminate/database is also a separate package. Seeing as this package is also depending on illuminate/container, I can change resolve($class) to Container::getInstance()->make($class) with a use Illuminate\Container\Container; statement at the top, to not break BC by changing the constructor.

@DuckThom DuckThom force-pushed the patch-1 branch 2 times, most recently from 01c6107 to 468fda0 Compare November 14, 2019 14:17
- Resolve migration classes via the container to allow DI in migrations
@taylorotwell
Copy link
Member

It's not needed. Use Facades. It seriously does not matter at all if you use facades in your migrations. It's good to just move past the superstition in this case.

@DuckThom
Copy link
Contributor Author

I don't see why it's a problem to resolve the classes using the container, it doesn't remove any current features, it only adds new possibilities.

Besides that, the main reason I don't like Facades is because IDE's can't autocomplete their methods without a third party module, and I don't want to install or add unnecessary dependencies to my apps if I can help it. So honestly, I don't see the benefits of using Facades over DI.

@driesvints
Copy link
Member

@DuckThom I personally also don't use facades much myself but in this particularly use case I don't see how DI provides benefit here. The point of a migration is to change a DB structure which you generally want to test as an integration test with a real database. I don't think that DI provides any benefit here. If you need more logic inside your migration than the default structure changes it might be best to extract to a separate class and unit test that class.

@DuckThom
Copy link
Contributor Author

@driesvints I agree that it doesn't provide a benefit to migrations but it also doesn't remove any existing functionality. It's more to be able to keep the code consistent with the rest of your codebase and to be able to use autocompletion in IDEs without adding extra dependencies in the app. This 2 line change just allows you to inject classes in the constructor of a migration in case it's needed.

I'll just keep my override then, just in case anyone else is looking for the same functionality, these are my changes:

In my service provider's register method I have:

$this->app->extend('migrator', function ($migrator, $app) {
    $repository = $app['migration.repository'];

    return new Database\Migrator($repository, $app['db'], $app['files'], $app['events']);
});

And the custom migrator class (removed some newlines to keep the codeblock shorter):

use Illuminate\Database\Migrations\Migrator as LaravelMigrator;

class Migrator extends LaravelMigrator {
    public function resolve($file) {
        $class = Str::studly(implode('_', array_slice(explode('_', $file), 4)));
        return Container::getInstance()->make($class);
    }
}

@driesvints
Copy link
Member

@DuckThom there's no need in adding code which won't be used.

@DuckThom
Copy link
Contributor Author

@driesvints Well that's kind of my point for having to use the extra dependency for facade IDE autocompletion aswell 😛

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants