5

我正在为 Orchard CMS 编写一个模块,其中包含一个实现IOrchardShellEvents接口的事件处理程序类。

当使用 Core 配方设置 Orchard 的库存实现并启用我的模块时,只有三个有效的IOrchardShellEvents. 默认情况下,它们按以下顺序调用:

  1. 我的自定义事件处理程序(在我的自定义模块中)
  2. AliasHolderUpdater(来自Orchard.Alias模块)
  3. AutomaticDataMigrations(从Orchard.Framework)。

我想设置这些,以便在触发适用的事件时,我的类被调用晚于AutomaticDataMigrations. 我已经尝试在我的模块中同时使用DependenciesPriority字段Modules.txt,但我无法让我的课程晚于AutomaticDataMigrations.

我尝试过的事情:

  • 我尝试将Dependencies: Orchard.Framework添加到我的模块的Module.txt. 这似乎无济于事。但是,当我将Dependencies: Orchard.Alias添加到 时Module.txt,我的课程确实比AliasHolderUpdater. 它只是不适用于AutomaticDataMigrations,这是Orchard.Framework.

  • 我尝试将Priority: 1添加到我的模块的Module.txt. 这确实会导致我IOrchardShellEvents的类比模块中存在的其他实现晚被调用,例如AliasHolderUpdater. 但是,即使那样,它仍然会AutomaticDataMigrations最后调用。

查看ExtensionManager.AvailableFeatures方法可以看出,所有的特征都是按照依赖和优先级的顺序加载的。这意味着IDependency来自每个模块的实际对象按此顺序向 AutoFac 注册。

(细节可以在DependencyOrdering.OrderByDependenciesAndPrioritiesCompositionStrategy.ComposeShellContainerFactory.CreateContainer方法中看到)

我没有看到一种方法来控制驻留在模块中的类相对于驻留在 中的类的注册顺序Orchard.Framework,这不是“果园模块”,也不遵循模块加载的正常规则。

因为 的目的AutomaticDataMigrations是确保最新的数据库迁移已经运行,所以我希望我的类在它之后被调用,这样当我的事件处理程序运行时,我可以确定它可以使用设置的数据库表由迁移。

我如何注册我的课程以晚于运行AutomaticDataMigrations?或者,这是否需要修改 Orchard 本身?

4

1 回答 1

1

我想我已经找到了这个问题的答案,我相信这实际上是 Orchard 中的一个错误。

Orchard.Environment.ShellBuilders.CompositionStrategy包含以下代码:

    var enabledFeatures = _extensionManager.EnabledFeatures(descriptor);
    var features = _extensionManager.LoadFeatures(enabledFeatures);

    if (descriptor.Features.Any(feature => feature.Name == "Orchard.Framework"))
        features = features.Concat(BuiltinFeatures());

特征描述符以“依赖”顺序从列表中返回EnabledFeatures()——列表中较早的项目不应依赖于列表中后面的项目。最终构建依赖容器时使用此顺序。

因为Orchard.Framework不应该依赖任何东西,而一切都可以依赖Orchard.Framework,所以这应该是第一位的......并且代码应该是这样的(这里只修改了最后一行):

    var enabledFeatures = _extensionManager.EnabledFeatures(descriptor);
    var features = _extensionManager.LoadFeatures(enabledFeatures);

    if (descriptor.Features.Any(feature => feature.Name == "Orchard.Framework"))
        features = BuiltinFeatures().Concat(features);

这样,当依赖项作为列表的一部分注入时(例如事件处理程序),内置功能应该首先出现,因为它们没有依赖项。

这解决了我的问题,因为我可以依赖Orchard.Framework-providedIOrcharShellEvents实现在自定义模块提供之前调用。

我已在 Orchard 问题跟踪器中将上述内容作为建议修复提交:http: //orchard.codeplex.com/workitem/20286

于 2014-01-03T04:25:55.110 回答