Laravel AppServiceProvider中基于模型的服务解析

Laravel AppServiceProvider中基于模型的服务解析,laravel,inversion-of-control,service-provider,Laravel,Inversion Of Control,Service Provider,给你一个简单的看法:我试图根据条件进行重定向。若请求满足给定目的地的条件,则将重定向到特定目的地 我有目的地模型,它有许多条件(条件模型)。我有许多扩展基本条件模型的条件,如DateCondition,LocationCondition等(由polimorphic关系生成)。每种条件类型都应具有“服务”,告知给定条件是否匹配请求。示例DateCondition应该有自己的DateConditionMatcher,它实现了ConditionMatcherInterface (只需公共函数匹配($c

给你一个简单的看法:我试图根据条件进行重定向。若请求满足给定目的地的条件,则将重定向到特定目的地

我有
目的地
模型,它有许多条件(条件模型)。我有许多扩展基本条件模型的条件,如
DateCondition
LocationCondition
等(由polimorphic关系生成)。每种条件类型都应具有“服务”,告知给定条件是否匹配请求。示例
DateCondition
应该有自己的
DateConditionMatcher
,它实现了
ConditionMatcherInterface

(只需
公共函数匹配($condition,$request)

我想用立体的开闭原理来写。首先,我想将
getMatcher()
函数直接添加到条件模型中,并为每种条件类型返回不同的
ConditionMatcher
,但有些条件匹配器需要在constructor中传递一些其他服务,因此这将迫使我将它们也注入到
条件
模型中,这是一种糟糕的做法

也许在ServiceProvider中使用上下文绑定可以解决这个问题,但是如何解决呢? 我不知道如何将模型耦合到正确的一个ConditionMatcher,然后像这样自由地使用它:

foreach ($destination->conditions as $condition){
       $isMatched = $this->conditionMatcher->match($condition, $request);
}
要始终在$this->ConditionMatcher下具有正确的条件匹配器。
我希望有人能理解我不太清楚的信息。

我一夜之间就有了一个主意,可以提供服务,让所有的媒人都能找到。此解决方案的唯一缺点是注入每个匹配器

class ConditionResolver implements ConditionResolverInterface
{
    /** @var ConditionMatcherInterface[] */
    private $conditionMatchers = [];

    public function __construct(
       DateConditionMatcher $dateConditionMatcher, 
       TimeConditionMatcher $timeConditionMatcher,
       LocationConditionMatcher $locationConditionMatcher
    ) {
       $this->conditionMatchers[DateCondition::class] = $dateConditionMatcher;
       $this->conditionMatchers[TimeCondition::class] = $timeConditionMatcher;
       $this->conditionMatchers[LocationCondition::class] = $locationConditionMatcher;
    }
}
因此,现在我能够使用正确的匹配器以这种方式(简化)给定条件:

它允许我向AppServiceProvider中的匹配器注入各种服务

$this->app->singleton(LocationServiceInterface::class, function($app){
   return new LocationService();
});

$this->app->singleton(DateConditionMatcher::class, function($app){
   return new DateConditionMatcher();
});

$this->app->singleton(TimeConditionMatcher::class, function($app){
   return new TimeConditionMatcher();
});

$this->app->singleton(LocationConditionMatcher::class, function($app){
    return new LocationConditionMatcher($app->make(LocationServiceInterface::class));
});

总的来说,我认为我做了一些事情,这将以更优雅的方式完成,但现在我把它当作一个答案。如果您有更好的解决方案,请分享:)

我一夜之间就有了一个想法,可以提供服务,让所有的匹配者都能找到。此解决方案的唯一缺点是注入每个匹配器

class ConditionResolver implements ConditionResolverInterface
{
    /** @var ConditionMatcherInterface[] */
    private $conditionMatchers = [];

    public function __construct(
       DateConditionMatcher $dateConditionMatcher, 
       TimeConditionMatcher $timeConditionMatcher,
       LocationConditionMatcher $locationConditionMatcher
    ) {
       $this->conditionMatchers[DateCondition::class] = $dateConditionMatcher;
       $this->conditionMatchers[TimeCondition::class] = $timeConditionMatcher;
       $this->conditionMatchers[LocationCondition::class] = $locationConditionMatcher;
    }
}
因此,现在我能够使用正确的匹配器以这种方式(简化)给定条件:

它允许我向AppServiceProvider中的匹配器注入各种服务

$this->app->singleton(LocationServiceInterface::class, function($app){
   return new LocationService();
});

$this->app->singleton(DateConditionMatcher::class, function($app){
   return new DateConditionMatcher();
});

$this->app->singleton(TimeConditionMatcher::class, function($app){
   return new TimeConditionMatcher();
});

$this->app->singleton(LocationConditionMatcher::class, function($app){
    return new LocationConditionMatcher($app->make(LocationServiceInterface::class));
});

总的来说,我认为我做了一些事情,这将以更优雅的方式完成,但现在我把它当作一个答案。如果您有更好的解决方案,请分享:)

您目前是如何为条件获取正确的条件匹配器的?您是否每次都需要这些匹配器的新实例,或者单个实例可以用于多个条件?(像管理类一样思考)不,我不需要这些匹配器的新实例,所以每个匹配器都应该是一个单例。我已经发布了我所做的解决方案,但如果您知道更好的解决方案,请与我们分享。您目前如何获得适用于该条件的正确条件匹配器?您是否每次都需要这些匹配器的新实例,或者单个实例可以用于多个条件?(像管理类一样思考)不,我不需要这些匹配器的新实例,所以每个匹配器都应该是一个单例。我已经发布了我所做的解决方案,但如果你知道更好的解决方案,请分享。