DCI上下文的大多数示例都是作为命令模式实现的。但是,在使用依赖注入时,在构造函数中注入依赖项并将参数发送到执行方法中很有用。比较Command模式类:
public class SomeContext
{
private readonly SomeRole _someRole;
private readonly IRepository<User> _userRepository;
// Everything goes into the constructor for a true encapsuled command.
public SomeContext(SomeRole someRole, IRepository<User> userRepository)
{
_someRole = someRole;
_userRepository = userRepository;
}
public void Execute()
{
_someRole.DoStuff(_userRepository);
}
}
使用依赖注入类:
public class SomeContext
{
private readonly IRepository<User> _userRepository;
// Only what can be injected using the DI provider.
public SomeContext(IRepository<User> userRepository)
{
_userRepository = userRepository;
}
// Parameters from the executing method
public void Execute(SomeRole someRole)
{
someRole.DoStuff(_userRepository);
}
}
最后一个看起来好一点,但我从来没有看到它像这样实现所以我很好奇是否有任何事情需要考虑。
答案 0 :(得分:1)
Command和DCI之间存在对比。在Command中,您可以分配对象之间的交互,在DCI中,您可以通过角色方法集中交互。在MoneyTRansfer示例中,帐户将无法撤销或存储,因为它们是没有行为的简单数据。但是在诸如Transfer之类的上下文中,角色将存在行为。因此,当源帐户角色绑定到帐户对象时,帐户对象将获取撤销行为,并且目标帐户也是如此。
在命令模式中,它们具有行为,但行为的执行在命令对象中编写脚本并可以传递。整个交互不是命令对象的一部分,但通常分布在参与对象之间。
在Marvin中,由于认识到大多数现代语言仅部分支持DCI,因此支持DCI的语言构建只能将角色绑定到构造函数中的对象。如何调用构造函数与上下文无关。这可确保对所有角色执行一次绑定。然后只能通过实例化另一个上下文来重新绑定。这不是DCI的约束,而是Marvin的设计选择。
关于一个上下文方法是否可以接受论证的问题,这有点哲学,但据我记得上次我用Trygve Reenskaug辩论时,我们同意他们可以接受争论,我知道我已经实施了一些例子(包括DCI site的转账)。