简体   繁体   English

DCI:如何使用依赖注入实现上下文?

[英]DCI: How to implement Context with Dependency Injection?

Most examples of a DCI Context are implemented as a Command pattern. DCI上下文的大多数示例都实现为命令模式。 When using Dependency Injection though, it's useful to have the dependencies injected in the constructor and send the parameters into the executing method. 但是,当使用依赖注入时,将依赖注入到构造函数中并将参数发送到执行方法中会很有用。 Compare the Command pattern class: 比较命令模式类:

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);
    }
}

With the Dependency injected class: 使用依赖项注入类:

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);
    }
}

The last one seems a bit nicer, but I've never seen it implemented like this so I'm curious if there are any things to consider. 最后一个似乎更好,但是我从未见过如此实现,所以我很好奇是否有任何需要考虑的事情。

There's a contrast between Command and DCI. Command和DCI之间有一个对比。 In Command you distribute the interaction between objects, in DCI you centralize the interaction through rolemethods. 在Command中,您可以分配对象之间的交互,而在DCI中,您可以通过角色方法来集中交互。 In the MoneyTRansfer example the accounts will not have the ability to withdraw or deposit becasue they are simple data with no behavior. 在MoneyTRansfer示例中,由于帐户是简单数据,没有任何行为,因此帐户将无法提取或存款。 however in a context such as Transfer that behavior will exist for the roles. 但是,在诸如Transfer之类的上下文中,角色将存在行为。 So when the source account role is bound to an account object the account object gets the withdraw behavior and the same is true for the destination account. 因此,当源帐户角色绑定到帐户对象时,该帐户对象将具有提款行为,而目标帐户也是如此。

In the command pattern they have the behavior but the execution of the behavior is scripted in the command object and can be passed around. 在命令模式中,它们具有行为,但是行为的执行在命令对象中编写了脚本,并且可以传递。 The entire interaction is not part of the command object but typically distributed between the participating objects. 整个交互不是命令对象的一部分,而是通常分布在参与对象之间。

In Marvin, a language build to support DCI as a result of the realization that most modern languages only partly supports DCI, you can only bind roles to objects in the constructor. 在马文(Marvin)中,由于大多数现代语言仅部分支持DCI,因此该语言构建为支持DCI,因此您只能将角色绑定到构造函数中的对象。 How you call the constructor is of no concern to the context. 调用构造函数的方式与上下文无关。 This ensures that the binding is done once for all roles. 这样可以确保对所有角色都进行一次绑定。 Rebinding is then only possible by instantiation of another context. 这样,重新绑定只能通过实例化另一个上下文来实现。 This is not a constraint from DCI but a design choice for Marvin. 这不是DCI的限制,而是Marvin的设计选择。

To the question about whether or not an context method can take arguments, it's a bit philosophical but as far as I remember the last time I debatted it with Trygve Reenskaug we agreed that they could take arguments and I know that I've implemented a few examples (the moneytransfer at the DCI site included) where they do. 关于上下文方法是否可以接受参数的问题,这有点哲学,但是据我记得上次我与Trygve Reenskaug辩论时,我们同意他们可以接受参数,并且我知道我已经实现了一些实例(包括DCI站点的汇款)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM