依赖注入的策略模式?
是否有一种优雅的方法来处理策略模式的依赖
注入
container.Register<IMakeCoffee, MakeLatte>();
container.Register<IMakeCoffee, MakeEspresso>();
container.Register<IMakeCoffee, MakeCappuccino>();
?在这些策略中,我将其注入我的构造函数:
public Barista(IEnumerable<IMakeCoffee> coffeeStrategies) {}
但是一旦我列出了所有策略,我怎么能说我想要 ?我现在正在做的是迫使imakecoffee
的每个实例具有一个咖啡馆枚举,我可以键入该枚举,以确定策略是什么类型。
public Coffee MakeCoffee(CoffeeType coffeeType)
{
var strat = coffeeStrategies.FirstOrDefault(s => s.CoffeeType == coffeeType);
return strat.MakeCoffee();
}
是否有一种更优雅的方式来唯一确定策略?枚举业务似乎很麻烦。
作为参考,我将Prism用于Xamarin表单应用程序,但我觉得这个问题是独立的。
Is there an elegant way to deal with dependency injection for the strategy pattern?
For instance, I have my dependency injector that I register a few different strategies with, like so:
container.Register<IMakeCoffee, MakeLatte>();
container.Register<IMakeCoffee, MakeEspresso>();
container.Register<IMakeCoffee, MakeCappuccino>();
And then when I want to access one of these strategies, I inject it into my constructor like:
public Barista(IEnumerable<IMakeCoffee> coffeeStrategies) {}
But once I have that list of all the strategies, how can I say I want this specific strategy? What I'm doing now is forcing each instance of IMakeCoffee
to have a CoffeeType enum that I can key off of to determine what type the strategy is.
public Coffee MakeCoffee(CoffeeType coffeeType)
{
var strat = coffeeStrategies.FirstOrDefault(s => s.CoffeeType == coffeeType);
return strat.MakeCoffee();
}
Is there a more elegant way to uniquely identify a strategy? The enum business seems cumbersome.
For reference, I am using Prism for a Xamarin Forms app, but I felt this question was framework independent.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
选择具有“咖啡类型”枚举的策略是有道理的,但是选择器查询在需要注意各种实施细节以进行选择的意义上是侵入性的,没有什么可以说咖啡的类型永远是任何给定策略的唯一歧视者。
我会保留详细信息,并让策略接口公开A
bool Isapplicable(CoffeeMakerStrateGyContext上下文)
方法,每个策略可以根据需要进行不同的实现。该方法可以将coffeetype
枚举作为参数,但是如果出现新策略,则需要更改签名,但需要更多数据来做出决定。相反,通过传递一些“策略上下文”对象,签名不需要更改(类似于我们使用EventArgs
用于事件参数的原因):选择器代码变为:
Selecting a strategy with a "coffee type" enum makes sense, but the selector query is intrusive in the sense that it needs to be aware of various implementation details in order to make a selection, and nothing says the type of coffee will always ever be the only discriminator for any given strategy.
I'd keep the details encapsulated, and have the strategy interface expose a
bool IsApplicable(CoffeeMakerStrategyContext context)
method that each strategy can implement differently as needed. The method could take theCoffeeType
enum as a parameter, but then the signature would need to change if a new strategy comes along but requires more data to make a decision; by instead passing some "strategy context" object, the signature doesn't need to change (similar to why we useEventArgs
for event parameters):The selector code becomes:
我的第一个想法是,缺乏歧视的工会使这种类型的水平更加令人沮丧。为了方便起见,要免费获得图案,我很想做类似的事情:
我认为您也许可以使用Di'd Decorator,但这有点混乱,因为链的底部必须返回无效,无论如何都会变得更加混乱。
My first thought is that a lack of discriminated unions make this more frustrating on a type level. For the convenience and to get the try get pattern for free I'd be tempted to do something like:
I thought you could perhaps use DI'd decorators, but it's a bit of a mess because the bottom of the chain would have to return null, making it more messy anyway.
您可以创建某种策略选择器:
然后您可以将选择逻辑放入实现中:
您可以从选择器的构造函数中需要
iEnumerable&lt; imakecoffee&gt;
您的选择逻辑。您的咖啡师会很高兴:
You could create some sort of a strategy selector:
And then you could place your selection logic into the implementation:
You could require your
IEnumerable<IMakeCoffee>
from the selector's constructor, or use any other technical way to implement your selection logic.Your barista would be happy: