数天后,研究和思考了很多关于这个最好的方法,使用Laravel我终于解决了最后解决。
我不得不说,这是特别困难的Laravel 5.2
,因为在这个版本中会议中间件仅在路由使用的控制器上执行,这意味着,如果由于某种原因,我用了一个控制器(不链接对于死记硬背),并尝试访问会议,这是不可能的。
所以,因为我不能使用会话,我决定使用URL参数,在这里你有解决方案,我希望你们中的一些人认为它有用。
所以,你有一个接口:
interface Service
{
public function execute();
}
然后一对夫妇的接口实现:
服务之一:
class ServiceOne implements Service
{
public function execute()
{
.......
}
}
服务两项。
class ServiceTwo implements Service
{
public function execute()
{
.......
}
}
现在最有趣的部分:有一个包含了与服务接口的相关性功能的控制器,但我需要dinamically解决它基于在使用输入ServiceOne或ServiceTwo。所以:
控制器
class MyController extends Controller
{
public function index(Service $service, ServiceRequest $request)
{
$service->execute();
.......
}
}
请注意,ServiceRequest,验证了请求中已经存在,我们需要解决的依赖参数(称之为'service_name'
)
现在,在AppServiceProvider我们可以通过这种方式解决依赖关系:
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;
}
}
所以现在所有的责任都是针对Resolver类的,这个cl屁股基本上使用传递给构造器的参数,那将被用作服务接口的实现类的返回全名(命名空间):
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;
}
}
嗯,我真的希望这有助于一些你的。
祝好!
---------- -----------编辑
我才意识到,这不是直接使用请求数据,里面是个好主意Laravel的集装箱,从长远来看真的会有一些麻烦。
最好的方法是直接注册所有可能的实例(serviceone和servicetwo),然后直接从控制器或中间件中解析其中的一个,然后是控制器“谁决定”使用哪种服务(从所有可用的)基于来自请求的输入。
最后它的工作原理是一样的,但它可以让你以更自然的方式工作。我不得不说,感谢rizqi。来自Laravel闲聊的问题频道的用户。
他亲自为此创建了一个黄金article。请阅读它,因为完全和正确地解决这个问题。
laravel registry pattern
一个很好的问题。 – simhumileco