1

这可能有点长,但我遇到了一个轻微的设计障碍。

对于初学者,我创建了一个 IoC(控制反转),其中包含专门研究服务定位器而不是依赖注入。(这也是用在 node.js 上运行的咖啡脚本编写的,启用了和谐代理)

容器非常简单。您创建一个容器对象的新实例并在全局或本地存储该变量。

Context    = require('ettore').Context
AppContext = new Context()
App = AppContext.create 'App'

在这种情况下,我还实现了一个管理子上下文的上下文对象(尽管我可能会把它拿出来)

要在容器中存储信息,请使用以下内容:

App.set 'Namespace.Controller.Action', 'Value goes here'
App.set 'Namespace.Controller.Action.Index', 'Value goes here x2'

这完美地工作并且解决依赖关系同样简单(也有能力使用异步方法)

App.resolve 'Namespace.Controller.Action' # 'Value goes here'
App.get 'Namespace.Controller.Action' # 'Value goes here'

这是一个很好的系统,但需要样板代码,并且需要预先通过 IoC 容器,而不是“在幕后”。所以我开始实现一个别名系统,它可以使之前的代码像这样工作:

NM = App.alias "Namespace"
NM.Controller.Action # 'Value goes here'

这使用 V8 引擎提供的和谐代理(回退到库使用)。

问题

问题很简单,但同时又很复杂(除非我想太多了……)。再次使用前面的示例,我们有两个组件:

命名空间.Controller.Action 命名空间.Controller.Action.Index

我的系统在第一个示例中完美运行,如果找到了一个已解决的依赖项,则返回一个已解决的依赖项。否则它将发出错误或返回 false。问题在于知道您是否应该返回依赖项或另一个代理对象,以便他们可以继续进行下去。

为了明确这一点:

系统通过代理逐个对象并返回(通常)相同的代理对象。这允许您拥有较长的名称空间或您选择的命名方案。如果调用以下语句:

命名空间.Controller.Action

它将通过系统 2 次。一个用于控制器,另一个用于操作。问题是你真的不知道当前对象是否附加了另一个对象。(例如,他们是否在操作后调用 .Index?)

现在我已经实现了一种不太好的承诺系统。对于当前的“循环”,它将检查完全限定名称是否存在依赖关系。如果是这样,那么它将在普通代理之外添加一个名为“then”的混合方法。

因此,如果您有以下命名空间:

Namespace.Controller.Action
Namespace.Controller.Action.Index

要访问“Namespace.Controller.Action”组件的内容,您必须使用 Promise,因为命名存在“冲突”。

Namespace.Controller.Action.then ->
   @get # 'Value goes here'
Namespace.Controller.Action.Index # 'Value goes here x2'

问题

有没有更好的方法来实现或解决这个问题?随着时间的流逝,我越来越近了,但有时这一切似乎都有些古怪。

源代码 出于显而易见的原因,我没有在此处发布完整的源代码,因为它很长。别名和容器的主要代码可以在这里找到:https ://github.com/TheHydroImpulse/Ettore/blob/master/lib/Container.coffee

一个示例文件,在这里使用相同的原则(别名)被发现:https ://github.com/TheHydroImpulse/Ettore/blob/master/examples/alias.coffee

注意:如果您需要我更详细地解释某些事情,请告诉我......这是一个奇怪的问题描述。

4

0 回答 0