finalmente dopo qualche giorno che ricercano e di pensare molto circa l'approccio migliore per questo, utilizzando laravel ho finalmente risolto.
devo dire che questo è stato particolarmente difficile in Laravel 5.2
, perché in questa versione la sessione middleware viene eseguito solo nei controllori utilizzati in un percorso, significa che se per qualche motivo ho utilizzato un controller (non legato per un rote) e cercare di ottenere l'accesso alla sessione non sarà possibile.
Quindi, poiché non posso utilizzare la sessione, ho deciso di utilizzare i parametri URL, ecco l'approccio della soluzione, spero che alcuni di voi l'abbiano trovato utile.
Quindi, avete un'interfaccia:
interface Service
{
public function execute();
}
Poi un paio di implementazioni per l'interfaccia:
Il servizio one:
class ServiceOne implements Service
{
public function execute()
{
.......
}
}
Il servizio due.
class ServiceTwo implements Service
{
public function execute()
{
.......
}
}
Ora la parte interessante: ha un controller con una funzione che hanno una dipendenza con l'interfaccia di servizio ma ho bisogno di risolverlo dinamicamente a ServiceOne o ServiceTwo sede in un ingresso uso. Quindi:
Il controller
class MyController extends Controller
{
public function index(Service $service, ServiceRequest $request)
{
$service->execute();
.......
}
}
prega di notare che ServiceRequest, convalidato che la richiesta già il parametro che abbiamo bisogno di risolvere la dipendenza (lo chiamano 'service_name'
)
Ora, nel AppServiceProvider siamo in grado di risolvere la dipendenza in questo modo:
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
}
public function register()
{
//This specific dependency is going to be resolved only if
//the request has the service_name field stablished
if(Request::has('service_name'))
{
//Obtaining the name of the service to be used (class name)
$className = $this->resolveClassName(Request::get('service_name')));
$this->app->bind('Including\The\Namespace\For\Service', $className);
}
}
protected function resolveClassName($className)
{
$resolver = new Resolver($className);
$className = $resolver->resolveDependencyName();
return $className;
}
}
Così ora tutto il responsibilty è per la classe Resolver, questo cl ass fondamentalmente utilizzare il parametro passato alla contructor di restituire il fullname (con spazio dei nomi) della classe che sta per essere usato come un'implementazione dell'interfaccia Servizio:
class Resolver
{
protected $name;
public function __construct($className)
{
$this->name = $className;
}
public function resolveDependencyName()
{
//This is just an example, you can use whatever as 'service_one'
if($this->name === 'service_one')
{
return Full\Namespace\For\Class\Implementation\ServiceOne::class;
}
if($this->name === 'service_two')
{
return Full\Namespace\For\Class\Implementation\ServiceTwo::class;
}
//If none, so whrow an exception because the dependency can not be resolved
throw new ResolverException;
}
}
Beh, spero davvero che aiuta ad alcuni di voi.
I migliori auguri!
---------- EDIT -----------
ho appena rendo conto, che non è una buona idea di utilizzare direttamente i dati di richiesta, all'interno del container di Laravel, farà davvero dei problemi a lungo termine.
Il modo migliore è registrare direttamente tutte le possibili istanze suportate (serviceone e servicetwo) e quindi risolverne una direttamente da un controller o un middleware, quindi il controller "che decide" quale servizio utilizzare (da tutto il disponibile) in base all'input della richiesta.
Alla fine funziona allo stesso modo, ma ti permetterà di lavorare in modo più naturale.
Devo dire grazie a rizqi. Un utente dal canale delle domande della chat di Laravel.
Ha creato personalmente un oro article su questo. Per favore leggilo perché risolva questo problema completamente e in modo molto corretto.
laravel registry pattern
Una buona domanda. – simhumileco