IOC 容器的策略设计模式 - 特别是 Ninject
我有一堂课需要使用策略设计模式。在运行时,我需要切换不同的算法以查看对应用程序性能的影响。
当前所讨论的类在构造函数中采用四个参数,每个参数代表一个算法。
如何使用 Ninject(或通用方法)我仍然可以使用 IOC 但使用策略模式?
当前的限制是我的内核(容器)知道每个算法接口,但只能绑定到一个具体类。目前我能看到的唯一方法是在构造时传递所有八种算法,但使用不同的接口,但这似乎完全没有必要。如果我不使用 IOC 容器,我就不会这样做,所以必须有某种方法来解决这个问题。
代码示例:
class MyModule : NinjectModule
{
public override void Load()
{
Bind<Person>().ToSelf();
Bind<IAlgorithm>().To<TestAlgorithm>();
Bind<IAlgorithm>().To<ProductionAlgorithm>();
}
}
Person 需要使用两种算法,以便我可以在运行时进行切换。但只有 TestAlgorithm 被绑定,因为它是容器中的第一个。
I have a class which is going to need to use the strategy design pattern. At run time I am required to switch different algorithms in and out to see the effects on the performance of the application.
The class in question currently takes four parameters in the constructor, each representing an algorithm.
How using Ninject (or a generalised approach) could I still use IOC but use the strategy pattern?
The current limitation is that my kernel (container) is aware of each algorithm interface, but that can only be bound to one concrete class. The only way around this I can see at the moment is pass in all eight algorithms at construction, but use different interfaces, but this seems totally uncessary. I wouldn't do this if I was not using an IOC container, so there must be some way around this.
Code example:
class MyModule : NinjectModule
{
public override void Load()
{
Bind<Person>().ToSelf();
Bind<IAlgorithm>().To<TestAlgorithm>();
Bind<IAlgorithm>().To<ProductionAlgorithm>();
}
}
Person needs to make use of both algorithms so I can switch at run time. But only TestAlgorithm is bound, as it's the first one in the container.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
让我们退后一步,看一下更大的图景。由于您希望能够在运行时切换策略,因此必须有某种信号机制告诉 Person 切换策略。如果您的应用程序是 UI 驱动的,也许有一个按钮或下拉列表,用户可以在其中选择要使用的策略,但即使情况并非如此,某些外部调用者也必须映射一块运行时数据到策略实例。
当您需要将运行时实例映射到依赖项时,标准 DI 解决方案是使用一个抽象工厂。
您无需向容器注册各个策略,而是注册工厂。
完全有可能编写一个完整的 API,使其DI 友好,但仍然与 DI 容器无关。
Let's take a step back and examine a slightly bigger picture. Since you want to be able to switch Strategy at run-time, there must be some kind of signalling mechanism that tells Person to switch the Strategy. If you application is UI-driven, perhaps there a button or drop-down list where the user can select which Strategy to use, but even if this is not the case, some outside caller must map a piece of run-time data to an instance of the Strategy.
The standard DI solution when you need to map a run-time instance to a dependency is to use an Abstract Factory.
Instead of registering the individual Strategies with the container, you register the factory.
It is entirely possible to write a complete API so that it's DI-friendly, but still DI Container-agnostic.
如果您需要在运行时改变
IAlgorithm
实现,您可以更改Person
以要求一个算法factory,该算法基于以下内容提供不同的具体算法:运行时条件。一些依赖注入容器允许您绑定到匿名创建委托 - 如果 Ninject 支持这一点,您可以将决策逻辑放入其中之一。
If you need to vary the
IAlgorithm
implementation at run-time, you can changePerson
to require an algorithm factory that provides different concrete algorithms based on run-time conditions.Some dependency injection containers let you bind to anonymous creational delegates - if Ninject supports that, you could put the decision logic in one of those.