I'm making a Laravel package and I'm using a service provider and a facade to make my class available.
I want that every time the user calls my class like ImageUpload::myfunc()
a new instance of the class ImageUploadManager
is created.
When I use app('imageupload')->myfunc()
it works the way I want it but i'd like something easier and "prettier" than that.
Is it possible? I'm not new to laravel but I'm somewhat new to ServiceProviders and Facades. From my understanding the only thing I needed to do was call the function bind
instead of singleton
.
I also understand that the service container is just a glorified array. So it makes sense that the key imageupload
is already instantiated so Laravel doesn't do it again, but other packages do it I just don't understand how.
My Facade:
class ImageUpload extends Facade
{
protected static function getFacadeAccessor()
{
return 'imageupload';
}
}
My Service Provider:
public function register(): void
{
$this->app->bind('imageupload', function ($app) {
return new ImageUploadManager();
});
}
In a controller somewhere
ImageUpload::myfunc(); //It's always the same instance
app('imageupload')->myfunc(); //It's a new instance everytime. This is what I want
After researching how other packages do it, I found one that was similar to mine and figured out how they did it.
Every time my class is called statically I create a new instance of it. I found this solution by looking at this package.
I changed my facade to this:
class ImageUpload extends Facade
{
protected static function getFacadeAccessor()
{
return 'imageupload';
}
public static function __callStatic($method, $args)
{
/** @var \Illuminate\Contracts\Foundation\Application|null */
$app = static::getFacadeApplication();
if (!$app) {
throw new RuntimeException('Facade application has not been set.');
}
// Resolve a new instance, avoid using a cached instance
$instance = $app->make(static::getFacadeAccessor());
return $instance->$method(...$args);
}
}
I don't know if this is the correct way to do it, it was the way that I found.