如何为DI / IOC订购我的ctor参数?
我有点像DI新手,所以请原谅我这是错误的做法还是一个愚蠢的问题。
假设我有一个创建/更新订单的表单,并且我知道它将需要检索要显示的产品和客户的列表。我想传递正在编辑的Order对象,但我也想将ProductsService和CustomersService注入为依赖项。
因此,我希望我的IoC容器(随身携带的其中一个容器)提供服务,但是由调用代码提供Order对象进行编辑。
我是否应该将构造函数声明为将Order对象作为第一个参数,并将ProductsService和CustomersService作为其后参数,例如:
public OrderForm(Order order, ProductsService prodsSvc, CustomersService custsSvc)
...或者依赖关系应该放在首位,而Order对象应该放在最后,例如:
public OrderForm(ProductsService prodsSvc, CustomersService custsSvc, Order order)
有关系吗?是否取决于我使用的IoC容器?或者,还有更好的方法?
解决方案
马特,我们不应将常规参数与依赖项混合使用。由于将在IoC容器的内部创建对象,因此如何指定必要的参数?
混合依赖项和常规参数将使程序的逻辑更加复杂。
在这种情况下,最好声明依赖项属性(即从构造函数中删除依赖项)或者在IoC构造OrderForm并解决其依赖项后初始化订单字段(即从构造函数中删除常规参数)。
我们还可以声明所有参数,包括作为依赖项的订单。
对于允许实例化OrderForm的实例而无需对Order实例的必需引用,我感到有些不安。原因之一可能是这将阻止我对空订单进行前期检查。还有其他想法吗?
我想让我感到欣慰的是,知道OrderForm对象将仅由Factory方法实例化,该方法可确保在调用IoC框架后设置Order属性。
我不同意@aku的回答。
我认为我们正在做的事情很好,还有其他做事的方法或者多或者少是不正确的。例如,一个人可能会质疑这个对象是否首先应该依赖于服务。
无论使用DI还是什么,我认为在脑海中至少阐明每个对象所处的状态是有帮助的,例如真实状态(订单),派生状态(如果有)和依赖项(服务):
http://tech.puredanger.com/2007/09/18/spelunking/
在任何构造函数或者方法上,我更喜欢首先传递真实数据,而最后传递依赖项或者外部内容。因此,在示例中,我希望使用第一个示例。