4

我已经使用了大量的依赖注入,但我想获得关于如何在运行时处理来自用户的信息的输入。什么是依赖注入用户输入的最佳策略?

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

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

好像逻辑路径的冲突与依赖注入的设计,但它是因为我的UI是针对特定类型的类中获取信息。

其他替代方案将包括使用IoC容器,让我通过额外的构造函数的参数,或者只是构建我需要在顶层的类,而无需使用依赖注入。

是否有这类问题的一个普遍接受的标准模式?

回答

4

这里有两条路可以走,根据您的需求。

1线的UI直接向您的具体类

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

的好处是,这种方式很简单,易于理解和执行。

不足之处是你的灵活性降低。您将无法任意替换一个实现与另一个实现(但是,然后再次,您可能不需要这种灵活性)。

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

2.添加一个抽象工厂

的另一种选择是增加一个间接的另一层。您可以不使用UI直接创建类,而是使用Abstract Factory来创建实例。

工厂的Create方法可以将端口号作为输入,所以这个抽象最好在UI子层中。

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

然后,您可以让您的DI容器线了这个工厂使用的端口号,并将其作为一个构造函数参数传送给真正实施的实现。其他工厂实现可能会忽略该参数。

这种方法的优点是你不会污染你的API(或你的具体实现),并且你仍然具有编程接口给你的灵活性。

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

0

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

我会避免添加一个“开始”方法等。它的更好的做法是(如果可能的话)总是让您的类处于有效状态,并且使用start方法切换到无参数构造函数会使您的类在这些类之间无效调用。这样做是为了测试(让它更好),让测试更加困难。

+0

对不起,我应该已经更清楚了。 com端口只是一个数字。测试不是问题,因为我可以创建类的模拟版本。提前不知道com端口,我从用户那里得到它。由于这种情况,使用户界面使用界面似乎很愚蠢,因为它需要一个需要com端口的实现。 – 2009-11-05 19:32:27