用户输入依赖注入的最佳策略是什么?

时间:2009-11-05 19:20:31

标签: dependency-injection inversion-of-control design-patterns

我已经使用了相当多的依赖注入,但是我希望获得有关如何在运行时处理用户信息的输入。

我有一个连接到com端口的类。我允许用户选择com端口号。现在,我将该com port参数作为构造函数参数。理由是,如果没有该信息,类就无法运行,并且它是特定于实现的(此类的模拟版本不需要com端口)。

另一种方法是使用“开始”方法接收com端口,或者具有设置com端口的属性。这使它与IoC容器非常兼容,但从类的角度来看它并不一定有意义。

似乎逻辑路由与依赖注入设计冲突,但这是因为我的UI正在获取特定类型类的信息。

其他替代方法包括使用IoC容器,它允许我传入额外的构造函数参数,或者只是在顶级构建我需要的类而不使用依赖注入。

对于这类问题,是否存在普遍接受的标准模式?

2 个答案:

答案 0 :(得分:4)

根据您的需要,您可以选择两条路线。

<强> 1。将UI直接连接到您的具体类

这是最简单的选择,但很多时候完全可以接受。虽然您可能拥有包含大量接口和DI的域模型,但UI构成了对象图的组合根,您可以在此处简单地连接您的具体类,包括您需要的端口号参数。

优点是这种方法简单易懂,易于实施。

缺点是你的灵活性会降低。您将无法随意替换另一个实现(但是,您可能不需要这种灵活性)。

即使将UI锁定为具体实现,这也不意味着域模型本身不能在其他应用程序中重复使用。

<强> 2。添加抽象工厂

另一种选择是添加另一层间接。它不是让您的UI直接创建类,而是使用抽象工厂来创建实例。

工厂的Create方法可以将端口号作为输入,因此这个抽象属于UI子层中的最佳。

public abstract class MyFactory
{
    public abstract IMyInterface Create(int portNumber);
}

然后你可以让你的DI容器连接一个使用端口号的工厂实现,并将它作为构造函数参数传递给你的实际实现。其他工厂实现可能只是忽略参数。

这种方法的优点是你不会污染你的API(或你的具体实现),你仍然可以灵活地为接口编程。

缺点是它增加了另一层间接。

答案 1 :(得分:0)

大多数IoC容器都有某种形式的Constructor Injection,允许您的IoC容器将模拟的COM端口传递到您的类中进行单元测试。这似乎是最干净的解决方案。

我会避免添加“开始”方法等。它更好的做法(如果可能)总是让你的类处于有效状态,并且使用start方法切换到无参数构造函数会使这些调用之间的类无效。这样做以启用测试只会让你的课程更难以测试(这应该会使它更好)。

相关问题